From: Anas Nashif Date: Tue, 13 Nov 2012 19:03:03 +0000 (-0800) Subject: Imported Upstream version 0.11.2 X-Git-Tag: upstream/0.11.2^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=84c8777941be4117603e8e7c6d51420b2828491a;p=platform%2Fupstream%2Flibwbxml2.git Imported Upstream version 0.11.2 --- 84c8777941be4117603e8e7c6d51420b2828491a diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..d034612 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,2 @@ +Main Developper: +Aymerick Jehanne \ No newline at end of file diff --git a/BUGS b/BUGS new file mode 100644 index 0000000..88a01a7 --- /dev/null +++ b/BUGS @@ -0,0 +1,18 @@ +1. Please read the TODO file for the limitations of the library. + +2. Please register to our ticket system (Trac): + +https://libwbxml.opensync.org/register + +3. Please check for an open/active ticket: + +https://libwbxml.opensync.org/report/1 + +4. Please create a new ticket: + +https://libwbxml.opensync.org/newticket + +Please note that a ticket is the most reliable way of communication. +If emails are ignored then a ticket still persists. +The tickets are checked before every release at minimum. + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..96bbf63 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,289 @@ +PROJECT( libwbxml C ) + +SET( LIBWBXML_VERSION_MAJOR "0" ) +SET( LIBWBXML_VERSION_MINOR "11" ) +SET( LIBWBXML_VERSION_PATCH "2" ) +IF( LIBWBXML_VERSION_BETA ) + IF( LIBWBXML_VERSION_BETA VERSION_GREATER 90 ) + MATH( EXPR LIBWBXML_VERSION_MINOR "${LIBWBXML_VERSION_MINOR} - 1" ) + SET( LIBWBXML_VERSION_PATCH ${LIBWBXML_VERSION_BETA}) + ELSE( LIBWBXML_VERSION_BETA VERSION_GREATER 90 ) + SET( LIBWBXML_VERSION_PATCH "beta${LIBWBXML_VERSION_BETA}" ) + ENDIF( LIBWBXML_VERSION_BETA VERSION_GREATER 90 ) +ENDIF( LIBWBXML_VERSION_BETA ) +SET( LIBWBXML_VERSION "${LIBWBXML_VERSION_MAJOR}.${LIBWBXML_VERSION_MINOR}.${LIBWBXML_VERSION_PATCH}" ) + +# The most recent interface number that this library implements. +#UPDATE: If any interface have been added, removed or changed since +#UPDATE: the last update increment CURRENT. +SET( LIBWBXML_LIBVERSION_CURRENT 1 ) + +# The implementation number of the CURRENT interface. +# UPDATE: Increment only if the library code has changed at all, since +# UPDATE: last release. +# UPDATE: Set REVISION to 0 if any interface have been added, removed or +# UPDATE: changed since the last update. +SET( LIBWBXML_LIBVERSION_REVISION 4 ) + +# The difference between the newest and the oldest interfaces. +# UPDATE: If any interface have been added since the last public +# UPDATE: release, then increment. +# UPDATE: If any interface have been removed since the last release +# UPDATE: reset to 0. +SET( LIBWBXML_LIBVERSION_AGE 0 ) + +# The range of implemention CURRENT - AGE is the SOVERSION +MATH( EXPR LIBWBXML_LIBVERSION_SOVERSION "${LIBWBXML_LIBVERSION_CURRENT} - ${LIBWBXML_LIBVERSION_AGE}" ) + +SET( LIBWBXML_LIBVERSION_VERSION "${LIBWBXML_LIBVERSION_SOVERSION}.${LIBWBXML_LIBVERSION_AGE}.${LIBWBXML_LIBVERSION_REVISION}" ) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.4) + +# TODO: Move to external file/macro +SET( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules" ) + +SET( LIB_SUFFIX "" CACHE STRING "The library directory suffix. 32bit empty string, 64 for 64bit." ) +SET( LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE INTERNAL "libary location" ) +SET( LIBDATA_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The library data directory" ) +SET( BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE INTERNAL "binary location" ) +SET( SHARE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share" CACHE INTERNAL "data location" ) +SET( INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE INTERNAL "headers location" ) +SET( LIBEXEC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/libexec" CACHE INTERNAL "libexec location" ) + +#MESSAGE(STATUS "CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}" ) + +SET( LIBWBXML_LIBRARIES_DIR "${LIB_INSTALL_DIR}" CACHE PATH "wbxml library location" ) +SET( LIBWBXML_INCLUDE_DIR "${INCLUDE_INSTALL_DIR}/libwbxml-${LIBWBXML_LIBVERSION_SOVERSION}.${LIBWBXML_LIBVERSION_AGE}" CACHE PATH "libwbxml headers location" ) +SET( LIBWBXML_BIN_DIR "${BIN_INSTALL_DIR}" CACHE PATH "wbxml binaries location" ) +SET( LIBWBXML_DATA_DIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "wbxml data location" ) +SET( LIBWBXML_EXEC_INSTALL_DIR "${BIN_INSTALL_DIR}" CACHE PATH "wbxml binary location" ) + +# find header files and type size +INCLUDE( CheckTypeSize ) +INCLUDE( CheckIncludeFiles ) +INCLUDE( Documentation ) +INCLUDE( AddDocumentation ) + +CHECK_INCLUDE_FILES( limits.h HAVE_LIMITS_H ) +CHECK_INCLUDE_FILES( ctype.h HAVE_CTYPE_H ) +CHECK_INCLUDE_FILES( stdlib.h HAVE_STDLIB_H ) +CHECK_INCLUDE_FILES( stdio.h HAVE_STDIO_H ) +CHECK_INCLUDE_FILES( stdarg.h HAVE_STDARG_H ) +CHECK_INCLUDE_FILES( assert.h HAVE_ASSERT_H ) + +# ensure out od source build +INCLUDE( MacroEnsureOutOfSourceBuild ) +MACRO_ENSURE_OUT_OF_SOURCE_BUILD("${CMAKE_PROJECT_NAME} doesn't allow to build within the source directory. Please, create a seperate build directory and run 'cmake ${PROJECT_SOURCE_DIR} [options]'!") + +# FIXME: popt is embedded into the source code +# popt is not used +# zlib is not used +# nsl is part of libc6 + +FIND_PACKAGE( Expat REQUIRED ) +FIND_PACKAGE( Check ) +FIND_PACKAGE( Iconv ) + +IF( EXPAT_FOUND ) + SET( HAVE_EXPAT 1 ) +ENDIF( EXPAT_FOUND ) + +IF(CHECK_FOUND) + OPTION( ENABLE_UNIT_TEST "enable unit tests" ON ) + INCLUDE( Testing ) +ENDIF(CHECK_FOUND) + +SET( WBXML_SUPPORT_ICONV OFF ) +IF( ICONV_FOUND ) + SET( HAVE_ICONV 1 ) + SET( WBXML_SUPPORT_ICONV ON ) +ENDIF( ICONV_FOUND ) + +# look for getopt implementation in unistd.h + +INCLUDE(CheckFunctionExists) +INCLUDE(CheckIncludeFile) + +CHECK_INCLUDE_FILE( "unistd.h" LIBWBXML_TOOLS_UNISTD_H ) +IF( ${LIBWBXML_TOOLS_UNISTD_H} ) + SET( CMAKE_REQUIRED_INCLUDES ${LIBWBXML_TOOLS_UNISTD_H} ) + CHECK_FUNCTION_EXISTS( getopt LIBWBXML_POSIX_GETOPT ) +ELSE( ${LIBWBXML_TOOLS_UNISTD_H} ) + SET( LIBWBXML_POSIX_GETOPT OFF ) +ENDIF( ${LIBWBXML_TOOLS_UNISTD_H} ) +IF( LIBWBXML_POSIX_GETOPT ) + OPTION( FOUND_POSIX_GETOPT "POSIX getopt" ON ) +ELSE( LIBWBXML_POSIX_GETOPT ) + OPTION( FOUND_POSIX_GETOPT "POSIX getopt" OFF ) +ENDIF( LIBWBXML_POSIX_GETOPT ) + +# look for the commands required for testing + +FIND_PROGRAM( PERL_PROGRAM "perl" ) +FIND_PROGRAM( DIFF_PROGRAM "diff" ) + +IF( PERL_PROGRAM ) + SET( ENABLE_PERL ON ) +ELSE( PERL_PROGRAM ) + SET( ENABLE_PERL OFF ) +ENDIF( PERL_PROGRAM ) + +IF( DIFF_PROGRAM ) + SET( ENABLE_DIFF ON ) +ELSE( DIFF_PROGRAM ) + SET( ENABLE_DIFF OFF ) +ENDIF( DIFF_PROGRAM ) + +OPTION( WBXML_LIB_VERBOSE "verbose mode" OFF ) +OPTION( WBXML_ENCODER_USE_STRTBL "enable string tables" ON ) +OPTION( WBXML_SUPPORT_WML "enable WML support" ON ) +OPTION( WBXML_SUPPORT_WTA "enable WTA support" ON ) +OPTION( WBXML_SUPPORT_SI "enable SI support" ON ) +OPTION( WBXML_SUPPORT_SL "enable SL support" ON ) +OPTION( WBXML_SUPPORT_CO "enable CO support" ON ) +OPTION( WBXML_SUPPORT_PROV "enable PROV support" ON ) +OPTION( WBXML_SUPPORT_EMN "enable EMN support" ON ) +OPTION( WBXML_SUPPORT_DRMREL "enable DRMREL support" ON ) +OPTION( WBXML_SUPPORT_OTA_SETTINGS "enable OTA_SETTINGS support" ON ) +OPTION( WBXML_SUPPORT_SYNCML "enable SYNCML support" ON ) +OPTION( WBXML_SUPPORT_WV "enable WV support" ON ) +OPTION( WBXML_SUPPORT_AIRSYNC "enable AIRSYNC support" ON ) +OPTION( WBXML_SUPPORT_CONML "enable Nokia ConML support" ON ) + +SET( PACKAGE "libwbxml" ) +SET( PACKAGE_BUGREPORT " " ) +SET( PACKAGE_NAME "libwbxml" ) +SET( PACKAGE_TARNAME "${PACKAGE_NAME}" ) +SET( PACKAGE_STRING "${PACKAGE_NAME} ${LIBWBXML_VERSION}" ) +SET( PACKAGE_VERSION "${LIBWBXML_VERSION}" ) +SET( VERSION "${LIBWBXML_VERSION}" ) + +CONFIGURE_FILE( "src/wbxml_config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/wbxml_config.h") +CONFIGURE_FILE( "src/wbxml_config_internals.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/wbxml_config_internals.h") +CONFIGURE_FILE( "libwbxml2.pc.cmake" "${CMAKE_CURRENT_BINARY_DIR}/libwbxml2.pc" @ONLY) + +# add uninstall target +CONFIGURE_FILE( "${CMAKE_SOURCE_DIR}/cmake/modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) + +ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") + +ADD_SUBDIRECTORY( src ) +ADD_SUBDIRECTORY( tools ) +ADD_SUBDIRECTORY( cmake ) + +MARK_AS_ADVANCED( CLEAR BUILD_DOCUMENTATION ) +#IF ( BUILD_DOCUMENTATION ) +# IF ( DOXYGEN_DOT_EXECUTABLE ) +# SET( HAVE_DOT "YES" ) +# ENDIF ( DOXYGEN_DOT_EXECUTABLE ) +# +# # configure tools documentation +# CONFIGURE_FILE( "tools/Doxyfile.in" "${CMAKE_CURRENT_BINARY_DIR}/tools/Doxyfile" @ONLY) +# ADD_CUSTOM_TARGET( DoxygenDocTools ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/tools/Doxyfile ) +# +# # configure library documentation +# CONFIGURE_FILE( "libsyncml/Doxyfile.in" "${CMAKE_CURRENT_BINARY_DIR}/libsyncml/Doxyfile" @ONLY) +# ADD_CUSTOM_TARGET( DoxygenDocLibrary ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/libsyncml/Doxyfile ) +# +# # configure general doxygen target +# CONFIGURE_FILE( "misc/doxygen.css" "${CMAKE_CURRENT_BINARY_DIR}/misc/doxygen.css" @ONLY) +# # WARNING: Do not use DEPENDS of ADD_CUSTOM_TARGET here +# ADD_CUSTOM_TARGET( DoxygenDoc ) +# ADD_DEPENDENCIES( DoxygenDoc DoxygenDocLibrary DoxygenDocTools ) +#ENDIF ( BUILD_DOCUMENTATION ) +OPTION( ENABLE_INSTALL_DOC "install documentation" ON ) +IF( ENABLE_INSTALL_DOC ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/AUTHORS ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/BUGS ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/ChangeLog ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/COPYING ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/GNU-LGPL ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/INSTALL ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/NEWS ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/README ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/References ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/THANKS ) + ADD_DOCUMENTATION( TEXT FILE ${CMAKE_SOURCE_DIR}/TODO ) +ENDIF( ENABLE_INSTALL_DOC ) + +# todo: add requires in pc file +INSTALL( FILES "${CMAKE_CURRENT_BINARY_DIR}/libwbxml2.pc" DESTINATION "${LIBDATA_INSTALL_DIR}/pkgconfig/" ) +# status output +INCLUDE( ShowStatus ) +MESSAGE( STATUS "==================================================" ) +SHOW_STATUS( WBXML_LIB_VERBOSE "verbose mode\t\t\t" ) +SHOW_STATUS( FOUND_POSIX_GETOPT "POSIX getopt\t\t\t" ) +SHOW_STATUS( ENABLE_UNIT_TEST "unit tests\t\t\t" ) +SHOW_STATUS( ENABLE_PERL "perl binary (test generated XML)" ) +SHOW_STATUS( ENABLE_DIFF "diff binary (test generated XML)" ) +SHOW_STATUS( WBXML_ENCODER_USE_STRTBL "enable string tables\t\t" ) +SHOW_STATUS( WBXML_SUPPORT_WML "enable WML support\t\t" ) +SHOW_STATUS( WBXML_SUPPORT_WTA "enable WTA support\t\t" ) +SHOW_STATUS( WBXML_SUPPORT_SI "enable SI support\t\t" ) +SHOW_STATUS( WBXML_SUPPORT_SL "enable SL support\t\t" ) +SHOW_STATUS( WBXML_SUPPORT_CO "enable CO support\t\t" ) +SHOW_STATUS( WBXML_SUPPORT_PROV "enable PROV support\t\t" ) +SHOW_STATUS( WBXML_SUPPORT_EMN "enable EMN support\t\t" ) +SHOW_STATUS( WBXML_SUPPORT_DRMREL "enable DRMREL support\t" ) +SHOW_STATUS( WBXML_SUPPORT_OTA_SETTINGS "enable OTA_SETTINGS support\t" ) +SHOW_STATUS( WBXML_SUPPORT_SYNCML "enable SYNCML support\t" ) +SHOW_STATUS( WBXML_SUPPORT_WV "enable WV support\t\t" ) +SHOW_STATUS( WBXML_SUPPORT_AIRSYNC "enable AIRSYNC support\t" ) +SHOW_STATUS( WBXML_SUPPORT_CONML "enable Nokia ConML support\t" ) +SHOW_STATUS( BUILD_DOCUMENTATION "build dynamic documentation\t" ) +SHOW_STATUS( WBXML_SUPPORT_ICONV "enable iconv support\t\t" ) +SHOW_STATUS( ENABLE_INSTALL_DOC "install documentation\t" ) + +# fatal error detection +IF ( FATAL_ERROR_EXPAT ) + MESSAGE( STATUS "==================================================" ) + MESSAGE( STATUS "FATAL ERROR(S) DETECTED ... DETAILS FOLLOW:" ) + MESSAGE( STATUS "==================================================" ) + IF ( FATAL_ERROR_EXPAT ) + MESSAGE( STATUS "${FATAL_ERROR_EXPAT}" ) + ENDIF ( FATAL_ERROR_EXPAT ) + MESSAGE( STATUS "==================================================" ) +ENDIF ( FATAL_ERROR_EXPAT ) + +### CPack ######################################## + +IF( RELEASE_CANDIDATE ) + SET( LIBWBXML_VERSION "${LIBWBXML_VERSION}-RC${RELEASE_CANDIDATE}" ) +ENDIF( RELEASE_CANDIDATE ) + +# ADD_SUBDIRECTORY( wbxmlTestSuite ) + +SET( CPACK_GENERATOR "TGZ;TBZ2" ) # This line is need for a CMake (Version 2.4.7) Bug - Fixed in CVS +SET( CPACK_SOURCE_GENERATOR "TGZ;TBZ2") +SET( CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${LIBWBXML_VERSION}" ) +SET( CPACK_SET_DESTDIR ON ) +INCLUDE( CPack ) + +### CTest ######################################## + +ENABLE_TESTING() +CONFIGURE_FILE( "tests/launchTests.sh" "${CMAKE_CURRENT_BINARY_DIR}/launchTests.sh") +CONFIGURE_FILE( "tests/normalize_xml.pl" "${CMAKE_CURRENT_BINARY_DIR}/normalize_xml.pl" @ONLY) +SET( activesync_tests 12 ) +SET( airsync_tests 4 ) +SET( ddf_tests 2 ) +# 2009-Jan-19 bellmich +# All DRMREL 1.0 tests are switched off. +# The background is the extremely bad specification. +# DRMREL 1.0 hardcodes the XML namespace translation. +# I never saw such a broken XML design before. +# +#SET( drmrel_tests 3 ) +SET( emn_tests 17 ) +SET( ota_tests 3 ) +SET( prov_tests 8 ) +SET( si_tests 25 ) +SET( sl_tests 13 ) +SET( syncml_tests 14 ) +SET( wv_tests 116 ) +SET( conml_tests 2 ) +FOREACH( TESTDIR activesync airsync conml ddf emn ota prov si sl syncml wv ) + FOREACH( ITEM RANGE 1 ${${TESTDIR}_tests} ) + ADD_TEST( "${TESTDIR}_${ITEM}" launchTests.sh "${CMAKE_SOURCE_DIR}/tests" "${TESTDIR}" ${ITEM} ) + ENDFOREACH( ITEM RANGE 1 ${${TESTDIR}_tests} ) +ENDFOREACH( TESTDIR activesync airsync conml ddf emn ota prov si sl syncml wv ) diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..89e5cc1 --- /dev/null +++ b/COPYING @@ -0,0 +1,24 @@ +libwbxml, the WBXML Library. +Copyright (C) 2002-2008 Aymerick Jehanne + +Please notice: The copyrights from other authors than + Aymerick Jehanne are placed in the affected files. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + +Contact: opensync-users@lists.sf.net +Home: http://libwbxml.opensync.org diff --git a/CTestConfig.cmake b/CTestConfig.cmake new file mode 100644 index 0000000..a4efcd2 --- /dev/null +++ b/CTestConfig.cmake @@ -0,0 +1,7 @@ +set(CTEST_PROJECT_NAME "libwbxml") +set(CTEST_NIGHTLY_START_TIME "00:00:00 CET") + +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "opensync.org") +set(CTEST_DROP_LOCATION "/testing/submit.php?project=libwbxml") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..04d300b --- /dev/null +++ b/ChangeLog @@ -0,0 +1,775 @@ +2012-07-20 Michael Bell + * libwbxml2.pc only depends on expat. It does not depend on libxml2. + The cmake module was fixed too. + * Install FindLibWbxml2.cmake during "make install" (ticket #83). + The external cmake modules are now included at cmake/modules + because the cmake directory includes a CMakeLists.txt. + * Removed outdated test/test_parser.c (ticket #82). + +2012-05-25 Michael Bell + * Released 0.11.1 + * Fixed performance problem during the generation of XML documents. + Committed the original patch from ticket #81. + The patch was supplied by Conrad Irwin. + * The parameter malloc_block of the function wbxml_buffer_create_real + is only used now for the initial memory allocation. The patch for + ticket #80 introduced a more agressive algorithm for memory + re-allocation to support big files. + * Fixed performance problem during the parsing of XML documents. + Committed the original patch from ticket #80. + The patch was supplied by Conrad Irwin. + * Extract node breaks (null'ed) the previous node link to a next node + (too early cleanup in wbxml_tree_extract_node of wbxml_tree.c). + The patch was supplied by Mark Ostrer from Websense (ticket #79). + * Added a trailing newline to the files THANKS and TODO (ticket #77). + * The tool xml2wbxml is now covered by LGPL v2.1 (or any later). + Petr Pisar discovered that wbxml2xml and xml2wbxml used different + licences. This was a mistake. Aymerick Jehanne and Michael Bell + (the copyright holders) agreed on using LGPL as licence. + (ticket #76) + +2011-08-06 Michael Bell + * Released 0.11.0 + * This is an exact copy of 0.11.beta6. + +2011-06-06 Michael Bell + * Released 0.11.beta6 + * Fixed handling of base64 encoded data in elements which are flagged + as WBXML_TAG_OPTION_BINARY. The base64 encoded data is only decoded + when all data is present (ticket #75). + * Added two new internal functions for the encoding and decoding of + base64 in a buffer (including cleanup of wbxml_encoder.c). The + decoder function supports formatted base64 strings too + (e.g. blanks, tabs and newlines). + * Added test for ticket #75 (formatted base64 string in binary tag). + * Failing tests do no longer remove their temporary data. + * Fixed wrong opaque conversion from WBXML to XML (never normalize + opaque/binary data). + * Added a new error code for the base64 decoder only. The decoder + used the same error code and message like the encoder until now. + * Added flag WBXML_TAG_OPTION_BINARY to tag MIME of ActiveSync code + page CompseMail:. + * Fixed otion -a of xml2wbxml (-a was not allowed as option). + * Added two tests for ActiveSync command SendMail. + * Fixed usage of strncasecmp and location of a variable definition + (changes from ticket #73). + This fixes some compiler errors from MS VisualStudio C++ 2010. + The patch was supplied by Boaz Yaniv. + +2011-04-27 Michael Bell + * Released 0.11.beta5 + * Fixed an inconsistency in the naming conventions of the new + functions. + +2011-04-19 Michael Bell + * Released 0.11.beta4 + * Added option -a to xml2wbxml (anonymous format). The public ID is + set to unknown and the DTD is not included. + +2011-04-14 Michael Bell + * Released 0.11.beta3 + * Some defines were added again to support the old libwbxml 0.9.2 + interface. This fixes mainly some names of parameter types. + You can compile libsyncml like follows: + CFLAGS="-I/usr/local/include/libwbxml-1.0/wbxml" cmake . -B/tmp/build/libsyncml + * If the XML root element must be used to identify the WBXML language + then the name space is scanned before the root element itself. + All SyncML versions use the same root element. Nevertheless it is + better to set the document type correctly. + * Fixed literal tag encoding. The element name and not the namespace + must be encoded. + * Added ActiveSync support with Microsoft's original namespaces. + +2011-01-25 Michael Bell + * Released 0.11.beta2 + * The WBXML converter interface is now more robust in terms of new + parameters and binary downward compatibility. + * Added workaround for Nokia bug. Some Nokia software does not only + encode the name space in the public ID. It also stores the name + space in the root element as an attribute with an attribute name + as literal reference zero but without a string table and the name + space as an inline string. + (Example: 04 00 03 string 00 => LITERAL index[0] STR_I string \0) + * Every enum element has a fixed number. + * Fixed SO-naming. + +2011-01-20 Michael Bell + * Released 0.11.beta1 + * Changed the location of the header files including the installation + path to support several versions of the library at the same host + * Header files are installed to separate directory wbxml/ + * Reduced API (removed 14 header files from installation) + * Removed unused parameter node from parse_cdata in wbxml_encoder.c. + (ticket #43) + * Fixed unused parameter warnings from expat callbacks. + (ticket #47, #48 and #49) + * Fixed wrong detection of WBXML language table list end. + (ticket #44 and #45) + * Added support for opaque tokens (e.g. byte arrays from Microsoft + ActiveSync, code page Email2 ConversationId and ConversationIndex) + (ticket #55). The original patch was supplied by Amnon Aaronsohn. + * Added new parameter -c for character set specification to wbxml2xml + (ticket #52) + * Added support for setting the character set in the transport + meta-information. This means that it is possible to set the + character set via the interface. Please note that you cannot + enforce a character set. (ticket #52) + +2011-01-08 Michael Bell + * Released 0.10.9 + * Added correct default behaviour to parse_charset. If no character + set is specified in a WBXML document then UTF-8 is assumed until + there is another specification in the transport meta-information. + (ticket #52) + * Fixed integer overflow in opaque data parsing (ticket #54). + The patch was supplied by Amnon Aaronsohn. + * Fixed iconv support (ticket #52) + * Added several tokens for Microsoft ActiveSync v14.0 revision 8.0 + (ticket #53). The patch was supplied by Amnon Aaronsohn. + * Fixed wrong WBXML table token for OMA DM DDF (ticket #51) + * Fixed unsigned integer overflow (patch from ticket #41) + The overflow causes crashs or wrong wbxml messages. + * Fixed locations of variable definitions and replaced strtoull by + strtoul (changes from ticket #42 and #50). + This fixes some compiler errors from MS VisualStudio 2008 and 9.0. + * Added support for recursion in wbxml_tree_node_elt_get_from_name + (ticket #46) + +2010-03-29 Michael Bell + * Released 0.10.8 + * Removed OMA DM tests because the OMA did not grant a permission + for the inclusion (ticket #36). + * Added a fix for the broken vFormat handling in the SyncML + specification. All LFs are replaced by CRLFs in every vFormat + object inside a SyncML message (ticket #38). + * Added Nokia ConML support (ticket #35). + There is no public documentation available from Nokia. The + transformation tables were created from sniffed WBXML documents. + The patch was supplied by Anton D. Kachalov. + +2009-05-12 Michael Bell + * Released 0.10.7 + * Fixed a Debian MIPS port build issue (ticket #34) + If the operating system environment has a built-in getopt + implementation then the cmake environment disables the internal + implementation of libwbxml and uses the getopt function of the + operating system. This avoids clashes with variables which are + declared extern and explicit but already exists in the default + POSIX header files (e.g. optopt). + +2009-04-24 Michael Bell + * Released 0.10.6 + * Extended (updated) tables for Microsoft AirSync + (The patch was supplied by Ossi Jormakka from Ixonos Plc.) + * Expat splits <html> into three separate text nodes. + Therefore it is necessary to scan for splitted text nodes + and merge them into a single consistent text node. + * Normalize encoding with normalize_xml.pl + * Fixed bashisms in launchTest.sh + * Fixed Sun Studio CC and GCC warnings. + * Fixed Testing.cmake to not set GCC specific compiler and linker + flags for other compilers. + * Fixed race condition in WV datetime opaque encoding + +2009-03-30 Michael Bell + * Released 0.10.5 + * Fixed library installation path for win32 (ticket #31) + (The patch was supplied by Jeremy Laine.) + +2009-03-09 Michael Bell + * Released 0.10.4 + * Fixed the byte order of the WV datetime opaque encoding (the bytes + were written in the reversed order) + * Fixed the time zone byte handling in the WV datetime opaque encoding + (e.g. A means UTC+1, Z must be 0x5a) (ticket #30) + * Added correct timezone handling for WV datetime opaque parser + * Added support for WV datetime inline encoding. All timestamps which + use the full ISO style like 2001-09-12T13:09:12+02:00 are encoded + as inline strings. This style is strongly recommended because time + zones like UTC+09:30 of Darwin in Australia are supported too. + (ticket #30) + * Added support for an EXPECTED value to the XML normalization script + +2009-02-17 Michael Bell + * Released 0.10.3 + * Added support for SourceParent in SyncML 1.1. + This is a proprietary extension to support things like the SMS and + bookmark synchronization of Nokia. + +2009-02-06 Michael Bell + * Released 0.10.2 + * Added support for OMA DM DDF 1.2 (ticket #7). + * DRMREL 1.0 test cases were disabled because of the poor + specification (e.g. hard coded names for XML namespaces and + definition of such namespaces as (WB)XML attributes). + * The generated XML documents of the most tests (conversion from XML + to WBXML back to XML) are compared with the original documents. + Only special tests are not covered (e.g. hexadecimal number + conversion, SyncML CDATA usage). + * If there is no PUBLIC ID then DOCTYPE must include PUBLIC "" or + SYSTEM. libwbxml always adds SYSTEM in this case. + * Fixed datetime support for Wireless Village (ticket #27). + * Extension tokens must not be replaced within normal text data + (ticket #26). + * Ticket #13 was rejected because the mentioned specification is only + a today outdated OMA change request. Perhaps a new specification + must be implemented in case of a new request. + * Created a script to normalize XML documents. + * The getopt implementation was replaced because of a potential + license issue. This fixed a Solaris build issue too (ticket #25). + +2009-01-06 Michael Bell + * Released 0.10.1 + * Removed a useless buffer which only creates a memory leak. + * The installation of the documentation can be disabled. + * LIBDATA_INSTALL_DIR was introduced (used by pkgconfig). + * All tests are executed as standalone tests to get more + detailed informations if a test fails. + * The timezone of the nightly build-time was fixed. + +2008-12-05 Michael Bell + * Released 0.10.0 + * Fixed ticket #14 with patch from ticket + (hexadecimal integer support for Wireless-Village) + * Added datetime encoding support for Wireless-Village. + (The encoder can tolerate missing seconds like in the tests.) + * Tests were integrated and can be used via make test. + * Build system switched to cmake from GNU autotools. + * Size changed to MaxSize in OMA DS 1.2 DevInf + * Fixed a couple of issues with SyncML, by Michael Bell + * Fixed segfault in wbxml_encoder.c + - Thanks Stijn van Drongelen + * Added Sax like entity parsing + * Miscellaneous build fixes and anonymous document support + * Namespaces support + * Some more cleanup and bug fixes + +2008-11-21 Aymerick Jehanne + * New release: 0.9.3 + * Project cleanup. + +2006-07-10 Aymerick Jehanne + * New release: 0.9.2 + * Finally applied fixes from OpenSync project and Debian libwbxml package + * Added XCode project for MacOS X + * Added Microsoft AirSync support + * Some more cleanup and bug fixes + * Windows and Symbian projects files are NOT up to date at all. Searching for mainteners. + +2005-12-19 Aymerick Jehanne + * wbxml_tree.c: Fixed wbxml_tree_node_get_syncml_data_type(). + +2005-11-28 Aymerick Jehanne + * SyncML 1.2 support + * Improved WBXMLTree API + * New encoder 'flow mode' + * Back to LGPL licence + +2005-05-23 Aymerick Jehanne + * wbxml_tables.c: Added the 'WBXML_SUPPORT_PROV_11' flag to activate + OMA PROV 1.1 tables. There is no new Public ID defined to OMA PROV 1.1. + I don't know how to handle this, so for the moment I apply the OMA PROV 1.1 + tables modifications directly into OMA PROV 1.0 tables. + +2005-04-01 Aymerick Jehanne + * wbxml_parser.c: Corrected a bug when Public ID is in string table. + Handle phones that don't end string table with a terminating NULL char. + Removed some potential memory leaks. + +2005-03-29 Aymerick Jehanne + * wbxml_tree.[h|c]: Added wbxml_tree_node_have_child_elt() + * wbxml_encoder.c: Added WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT + to disable indent of elements that do not have child elements, for + a more readable XML generation. This flag should be replaced by + a configuration var later. + +2005-03-20 Aymerick Jehanne + * Work on Symbian port / Start of SyncML wrapper / Some cleanup + +2005-03-16 Aymerick Jehanne + * src/wbxml_encoder.c: Do not generate string table for OTA Settings + documents (thanks to Rasmus Lock Larsen). + +2005-03-10 Aymerick Jehanne + * src/wbxml_tables.c: Changed 'NumberOfChanged' to 'NumberOfChanges' + in SyncML table (thanks to Frank Sprague). + +2005-03-01 Aymerick Jehanne + * doc/: Removed deprecated files. + * web/: Removed folder. + +2005-02-24 Aymerick Jehanne + * src/wbxml_parser.c: Fixed bug [1080489] (thanks to Rasmus Lock Larsen) + * src/wbxml_encoder.c: Added a 'WBXML_ENCODER_XML_GEN_EMPTY_ELT' flag + to enable generation of '' instead of ''. This flag + should be replace to a configuration var later. + +2005-02-23 Aymerick Jehanne + * src/wbxml_tree.[h|c] : Added wbxml_tree_node_destroy_all(). + +2005-02-22 Aymerick Jehanne + * src/wbxml_tree.[h|c] : Added wbxml_tree_extract_node(). + +2005-02-17 Aymerick Jehanne + * src/wbxml.h, src/wbxml_conv.[h|c], src/wbxml_elt.[h|c], + src/wbxml_encoder.c, src/wbxml_tree.[h|c], + src/wbxml_tree_clb_wbxml.c, src/wbxml_tree_clb_xml.c, + tools/wbxml2xml_tool.c, tools/xml2wbxml_tool.c : Work continue + on new wbxml_tree.h interface + + * src/wbxml_buffers.h: typo correction + +2005-02-17 Aymerick Jehanne + * src/wbxml_tree.c, src/wbxml_tree_clb_xml.c : Implemented + wbxml_tree_add_elt() + +2005-02-16 Aymerick Jehanne + * src/wbxml.h, src/wbxml_conv.[h|c], src/wbxml_elt.h, + src/wbxml_encoder.[h|c], src/wbxml_tables.[h|c], + src/wbxml_tree.[h|c], src/wbxml_tree_clb_wbxml.c, + src/wbxml_tree_clb_xml.c, tools/wbxml2xml_tool.c: + - started to work on new wbxml_tree API + - refactored wbxml_tree.c and wbxml_conv.c + - some typo fixes and code clean-up + +2005-02-11 Aymerick Jehanne + * all files cleanup: replaced tabs by 4 spaces, and forced Unix + files format + * WV test suite fixes + +2005-02-08 Aymerick Jehanne + * src/wbxml_conv.[h|c], src/wbxml_encoder.c, + tools/wbxml2xml_tool.c, tools/xml2wbxml_tool.c : Renamed + wbxml_conv_wbxml2xml() and wbxml_conv_xml2wbxml() functions, + then added two macros to permit wbxml_conv.h interface + backward compatibility + * src/wbxml_encoder.c: Fixed a bug that produced non valid XML + by not replacing '<' and '&' characters to their entity values + +2005-02-02 Aymerick Jehanne + * src/wbxml_charset.c: clean-up + * src/wbxml_tables.c: WV 1.2 - Reviewed tables to apply + OMA-IMPS-WV-CSP_WBXML-V1_2-20040522-C.pdf + +2005-02-01 Aymerick Jehanne + * Some files: Typo corrections + * All files: Copyright update + * Lot of files: First work on multiple charsets + handling, using libiconv + +2004-09-20 Aymerick Jehanne + * New release of wbxml2: 0.9.1 + +2004-09-20 Aymerick Jehanne + * src/wbxml_parser.c: Modified parse_content() + to handle correctly a SyncML content generated + by a Nokia 6600 + +2004-02-29 Aymerick Jehanne + * New release of wbxml2: 0.9.0 + +2004-02-28 Aymerick Jehanne + * src/wbxml_tables.h: Corrected WBXML Public Ids for + SyncML 1.0 and DevInf 1.0 (hope, this is a good + choice...) + +2004-02-26 Aymerick Jehanne + * src/wbxml_parser.c: Initialize wbxml version + to WBXML_VERSION_10 in parse_version() before + parsing (thanks to Thomas Butter). + * src/wbxml_parser.c: Added support for Altitude, + Accuracy and Cpriority presence attributes + in decode_wv_content() (thanks to Erik). + * src/wbxml_parser.c: Modified decode_wv_integer() + to allow decoding of '0 length' integers + (thanks to Erik) [Example: 'C3 80 00 01']. + +2004-02-25 Aymerick Jehanne + * New license: GNU GPL + * New website: http://libwbxml.aymerick.com + +2004-01-13 Aymerick Jehanne + * src/wbxml_encoder.c: Corrected CDATA encoding. + Now CDATA is encoded into Opaque [to be tested + with real phones] + * src/wbxml_parser.c: Added debug info + +2004-01-11 Aymerick Jehanne + * Added Symbian Port + * Added CDATA Support + * src/wbxml_tables.h: Corrected WBXML Public Ids for + SyncML 1.1 and DevInf 1.1 (Thanks to Miguel Coca) + +2003-11-24 Aymerick Jehanne + * New release of wbxml2: 0.8.2 + - This is the last release before moving to + 'happycoders.net' framework + - This is the last release under LGPL licence + +2003-11-23 Aymerick Jehanne + * src/wbxml_buffers.c: Corrected initializations. + +2003-11-19 Aymerick Jehanne + * src/wbxml_encoder.c: Patched xml_encode_text() for SyncML + support. Thanks to Bo Lincoln. + +2003-11-01 Aymerick Jehanne + * src/wbxml_base64.[h|c]: Added base64 support. + * testsuite/drmrel/: Added DRMREL 1.0 Test Suite. + * Added support of for DRMREL 1.0 in Parser + and Encoder. + * Added Leak Tracker. + * New release of wbxml2: 0.8.1 + +2003-10-28 Aymerick Jehanne + * Moved WBXML Versions tokens to an Enumeration. + * Added possibility to choose the WBXML Version when encoding + to WBXML. + +2003-10-20 Aymerick Jehanne + * Lot of code fixes / clean-up + * New release of wbxml2: 0.8.0 + +2003-10-18 Aymerick Jehanne + * Lot of work on SyncML : Now, XML to WBXML encoding should work. + This must be tested a bit more, but it seems to work fine :) + * testsuite/syncml/ : Some SyncML test files has been corrected. + * src/wbxml_tables.c : SyncML Table has been corrected. + * src/wbxml_tables.[c|h] : Added MetInf 1.0 Public ID + (thanks to Bo Lincoln) + * Lot of Doxygen fixes + +2003-10-17 Aymerick Jehanne + * Refactored code: + - Removed 'conv/' directory and moved code to 'src/'. + - Added 'HAVE_EXPAT' compile flag. + - Renamed some files, fonctions, etc... + +2003-10-15 Aymerick Jehanne + * src/wbxml_encoder.c : In parse_attribute(), return 'WBXML_OK' + if there is no Attribute Table (ie: do not stop encoding). + This is needed for SyncML. + +2003-08-02 Aymerick Jehanne + * New release of wbxml2: 0.7.3 + +2003-06-25 Aymerick Jehanne + * src/wbxml.h, wbxml_encoder.[h|c], wbxml_parser.c, + wbxml_tables.[c|h] : Corrected SyncML WBXML Parsing and + SyncML XML Encoding. + +2003-06-24 Aymerick Jehanne + * src/wbxml_buffers.[c|h] : Added wbxml_buffer_compare_cstr() + * src/wbxml_tree.[c|h] : Added a new Node Type 'WBXML_TREE_TREE_NODE' + and the search function wbxml_tree_get_element_node_from_name() + * src/wbxml_tree_clb.c : Handle parsing of SyncML encapsulated WBXML + documents + * src/wbxml_encoder.c : XML Encoding of encapsulated WBXML documents + * src/wbxml_tables.h : Corrected DevInf 1.0 XML ID + +2003-06-03 Aymerick Jehanne + * testsuite/syncml, testsuite/testsuite.xml : Started a SyncML + Test Suite. Only 4 documents seems to work... mMm... too bad :-/ + +2003-05-26 Aymerick Jehanne + * conv/Makefile.am, tools/Makefile.am : Added WBXML_LANG_OTA_SETTINGS. + * wbxml_tables.c : Removed bugs when XML Header is not fully filled + (thanks to Nicolas Bougues). + * tools/xml2wbxml_tool.c, tools/wbxml2xml_tool.c : Added support of + stdin and stdout (thanks to Nicolas Bougues). + +2003-05-23 Aymerick Jehanne + * testsuite/ota, testsuite/testsuite.xml : Added OTA Settings + Test Suite. + * src/wbxml_parser.c, src/wbxml_encoder.c: Modified the way the lib + handle WBXML Versions. + * tools/wbxml2xml_tool.c : Added OTA Settings forcing support. + +2003-05-22 Aymerick Jehanne + * Added support of Ericsson / Nokia OTA Settings v7.0. Thanks + to Nicolas Bougues for the hints. + * src/wbxml.h : Added WBXML_LANG_OTA_SETTINGS. + * src/wbxml_tables.[h|c] : Added tables for OTA Settings. + * src/Makefile.am : Added WBXML_LANG_OTA_SETTINGS compilation flag. + * INSTALL : Added documentation of WBXML_LANG_OTA_SETTINGS. + * src/wbxml_tables.h : Added a true value for WBXML_PUBLIC_ID_WV_CSP11, + as found at 'http://www.openmobilealliance.org/tech/omna/ + omna-wbxml-public-docid.htm'. XML Public ID is different too... maybe + we have to switch to it... one day + +2003-05-02 Aymerick Jehanne + * Added compilation flag WBXML_ENCODER_USE_STRTBL. If not defined, + the String Table mecanism is not used (but it is still used + for unknown WBXML Public ID). + +2003-05-01 Aymerick Jehanne + * src/wbxml.h: Added a new enum 'WBXMLLanguage' to identify + each language supported. So that we don't rely on WBXML Public + ID (some languages doesn't have one). + * src/wbxml_tables.[h|c]: Modified 'WBXMLLangEntry' structure to + associate a 'WBXMLLanguage' for each language. Added a new + function wbxml_tables_get_wbxml_publicid() to get the WBXML + Public ID of a given Language. + * src/wbxml_parser.[h|c]: + - Use the new 'WBXMLLanguage' enum. + - Added a new parameter to wbxml_parser_parse_to_tree() to + force to parse the document to a given Language. + - Added wbxml_parser_set_language() that replaces the old + wbxml_parser_set_wbxml_public_id(). + - Changed wbxml_parser_get_wbxml_public_id() and + wbxml_parser_get_xml_public_id() behaviour. + * src/wbxml_encoder.c: Use the new 'WBXMLLanguage' enum. + * conv/wbxml_conv.h: Added the 'lang' parameter to + WBXML2XMLParameters structure. + * conv/wbxml2xmlc.: Use wbxml_parser_set_language() in Direct Mode. + Use the new parameter of wbxml_parser_parse_to_tree() in Tree Mode. + * tools/wbxml2xml_tool.c: Added '-l' option so that the user can + force parsing of document to a given Language. + * win32/*.dsp, conv/Makefile.am, src/Makefile.am, tools/Makefile.am, + tools/wbxml2xml_tool.c, src/wbxml.h, src/wbxml_errors.h, + src/wbxml_log.h, src/wbxml_encoder.c, src/wbxml_errors.c, + src/wbxml_log.c, wbxml_parser.c, wbxml_tables.c: Added compilation + flags for selecting supported languages. + +2003-04-30 Aymerick Jehanne + * src/wbxml.h : Added #pragma for WIN32 plateform, so that + some hidden warnings generate errors. Thanks to Ramki for + it's ARM compilation support ;) + * src/*, conv/*, tools/* : Modified numerous files to + correct this 'new' errors. Modified some structures (mainly + in 'src/wbxml_tables.h', and added some macro for automatic + casts so that we don't have to modify the API. Most of the + modifications concern WB_TINY to WB_UTINY casts. + +2003-04-26 Aymerick Jehanne + * New release of wbxml2: 0.7.2 + +2003-04-26 Aymerick Jehanne + * src/wbxml.h: Casted strlen(), strdup(), strcmp(), strncmp() + and strstr() parameters to (const char*) in macros. + * src/wbxml_tables.[h|c]: Added function + wbxml_tables_contains_attr_value_from_xml() + * wbxml_encoder.c: + - Changed WBXML_ENCODER_STRING_TABLE_MIN to '3'. + - In wbxml_strtbl_collect_strings(): check if the attribute + value is tokenisable before adding it to string table. + - In wbxml_encode_value_element_buffer(): corrected a bug + when splitting the buffer for String Table elements + +2003-04-25 Aymerick Jehanne + * testsuite/prov: Added OMA Prov 1.0 Test Suite + * src/wbxml_tables.c: Updated Prov 1.0 tables + (added new OMA elements / attributes) + * src/wbxml_encoder.c: Ignore blanks Text Node when building + String Table + +2003-04-24 Aymerick Jehanne + * Changed 'CR-LF' to 'LF' in all source files and Makefiles. + This should permits Linux users to compile normally. + Thanks to Jannes Faber for finding this solution. + +2003-04-19 Aymerick Jehanne + * Added Parsing of WV DateTime - Encoding not yet finished + * src/wbxml_tables.c : wbxml_tables_get_attr_from_xml() - check if + attr table is NULL ... thanx to Bo Lincoln + +2003-03-26 Aymerick Jehanne + * wbxml_encoder.c, wbxml_tables.c: More work on WV. Now Extension + tokens are generated, even while encoding simple String. + +2003-03-25 Aymerick Jehanne + * wbxml_errors.[h|c]: Added 'WBXML_NOT_ENCODED' and + 'WBXML_ERROR_WV_INTEGER_OVERFLOW' error codes. + * wbxml_encoder.c: Added wbxml_encode_wv_content() and + wbxml_encode_wv_integer() functions. Now WV Integers are encoded + correctly. + * wbxml.h: Added 'enum WBXMLWVDataType_e', that is used in Encoder + and in Parser. + * wbxml_tables.[h|c]: Added wbxml_tables_get_ext_from_xml() to + get an Extension Token from tables. + * wbxml_parser.c: Added decode_opaque_content() and + decode_wv_integer(). Now WV Integers are decoded correctly. + +2003-03-24 Aymerick Jehanne + * wbxml_tables.[c|h]: wbxml_tables_get_attr_from_xml(): modified for + better behaviour. Now it returns the attribute value part that is + not included in Attribute Token returns. + * wbxml_encoder.c: Now use wbxml_tables_get_tag_from_xml() and + wbxml_tables_get_attr_from_xml(). + * conv/xml2wbxml_clb.c: Modification due to changes of + wbxml_tables_get_attr_from_xml() prototype. + +2003-03-23 Aymerick Jehanne + * wbxml_tables.[h|c]: Added Wireless-Village 1.2 tokens. This is taken + from a Beta spec from OMA that contains some bugs. Hope this will be + corrected in next release of the spec. Corrected XML Public ID and + DTD of OMA WV 1.1. + * wbxml_tables.c: Added macro WBXML_TABLES_SEPARATE_WML_VERSIONS. + If undefined, only WML 1.3 tables are used, for all versions of WML. + * testsuite/wv: Corrected for OMA WV 1.1 + +2003-03-22 Aymerick Jehanne + * Added 'testsuite/emn': E-Mail Notification 1.0 Test Suite + * src/wbxml_encoder.c, src/wbxml_parser.c: Added encoding/decoding + of EMN 1.0 'timestamp' attribute + +2003-03-21 Aymerick Jehanne + * New release of wbxml2: 0.7.1 + +2003-03-20 Aymerick Jehanne + * Added /doc directory, with Docbook file and generated HTML + * Added /web directory, with the few website files + * Worked with Pau Alliagas on Linux port + +2003-03-19 Aymerick Jehanne + * Review the header files include mecanism + * Debug + +2003-03-17 Aymerick Jehanne + * Added Encoding/Decoding of SI %Datetime Attribute Values + * Added /testsuite/testsuite.xml Index File + * Added /testsuite/si/si-022.xml, /testsuite/si/si-023.xml, + /testsuite/si/si-024.xml, /testsuite/si/si-025.xml + +2003-03-16 Aymerick Jehanne + * New 'wbxml2' branch. A lot of changes: + - Now, we have two libraries: + - libwbxml2 (standalone) + - libwbxml2_conv (needs libwbxml2 and Expat libraries) + - A new representation of WBXML Document: The WBXMLTree + - Review of tokenisation of Attribute Values + - etc... + * The Makefile for wbxml2xml and xml2wbxml tools is not finished + +2003-02-21 Aymerick Jehanne + * src/Makefile.am: Removed definition of WBXML_LIB_VERBOSE, + replaced by the '-DWBXML_LIB_VERBOSE' CFLAG in src/Makefile.am + (thanks to Pau Aliagas) + +2003-02-03 Aymerick Jehanne + * wbxml_tables.c: Fixed "WVCSPFeat" attribute + * bootstrap: chmoded correctly + +2003-01-28 Aymerick Jehanne + * New release v0.6.1 (not yet packaged) + +2003-01-27 Pau Aliagas + * Adapt to autotools + * Build dynamic library + * Create a spec file for rpm + +2003-01-25 Aymerick Jehanne + * wbxml_tables.c: Removed a bug in 'sv_prov10_attr_table'. + Thanks to Pau Aliagas. + * src/wbxml_parser.c and test/parser_clb.c: Removed a bug + with empty attribute value. + +2002-12-08 Aymerick Jehanne + * New release v0.6 + +2002-12-08 Aymerick Jehanne + * wbxml_parser.c : Removed bug when parsing Literal Tag + * wbxml_buffers.c : Removed bug in wbxml_buffer_create() + * wbxml_encoder.c : Now encode Literal Attribut Names and Tags + * Added Leak Tracker Support in several files + * Redone a new 'makefile' (still needs 'configure' to searche for LibXML2) + +2002-12-07 Aymerick Jehanne + * Added wbxml_lists.[h|c]: List module needed by String Table handling in + wbxml_encoder.c. + * Added support of String Table in WBXML Encoder (still needs testing) + * Still needs: + - Apply String Table to attribute values + - Handle Literal tags and Attribute Names + +2002-12-04 Aymerick Jehanne + * Changed the Log Mecanism: Added Macros with variable parameters number + +2002-12-01 Aymerick Jehanne + * More work on Wireless-Village CSP + +2002-11-24 Aymerick Jehanne + * Added first version of WBXML Encoder... not really tested yet + * Todo in WBXML Encoder: + - Remove Ignorable XML Whitespaces before parsing + - Handle String Table + - Parse CDDATA + - Parse PI + - Encode Literal tags and Literal attribute names + - Correctly encode the attribute values (not only as Inline Strings) + - Handle Charsets Encoding + +2002-11-14 Aymerick Jehanne + * Commited Benedykt Kroplewski modifications + +2002-11-11 Benedykt Kroplewski + * Correct simple lenght variable bug in wbxml lib and parser + * Correct macros for compile with my Slackware linux... + * Make more detailed debug messages... + * Added SyncMl 1.0 definitions...(my phone use it) + +2002-11-11 Aymerick Jehanne + * Reorganized DLLs to start coding of a WBXML Encoder: + - wbxml_common: Common WBXML Functions + - wbxml_parser: WBXML Parser + - wbxml_encoder: WBXML Encoder + * wbxml_tables.c: New function wbxml_table_get_main() to get pointer on main WBXML Languages Table + * wbxml_parser.c: Modified to use wbxml_table_get_main() + * New files wbxml_encoder.[h|c]: nothing inside for now + * Removed file wbxml_types.h => moved into new file wbxml.h + * New magic macro "WBXML_DECLARE" for automatic DLL export under Windows, so lot of files has been + updated to use this macro + +2002-09-22 Aymerick Jehanne + * Added a best effort mode (WBXML_PARSER_BEST_EFFORT define). + * New release v0.5 + +2002-09-08 Aymerick Jehanne + * Removed bug in parse_attr_start() for 'attrCodePage' search. + +2002-08-16 Aymerick Jehanne + * Changed a stupid logic in wbxml_buffers.c for memory management (gosh) + +2002-08-15 Aymerick Jehanne + * Changed all Tabs to '4 spaces' + * Changed root element of WTA WML 1.2 to 'wta-wml' + * Changed 'Channel 1.2' token from 0x0D to 0x0E. I don't really understand if Channel 1.2 Public ID + is "-//WAPFORUM//DTD DLREL 1.0//EN" or "-//WAPFORUM//DTD CHANNEL 1.2//EN" + (http://www.wapforum.org/wina/wbxml-public-docid.htm) + * Added Token an Attribute tables for Wireless Village CSP 1.1, but it's not really usefull, because + there is no PublicID defined for it. I have to implement support of Extension Tokens for CSP 1.1 too... + but... well... why have they defined use of Extension Tokens instead of normal Attribute Value Table ?? + +2002-08-03 Aymerick Jehanne + * Enum and Struct naming clean-up + * Added "NULL" line in sv_table_entry to avoid crash if publicId not found. + * New release v0.4 + +2002-07-13 Aymerick Jehanne + * Makefile for Linux done (only tested with Cygwin) + * src/wbxml_parser.c: Removed duplicate WBXMLParser Typedef (Linux Error generated) + * test/parser_tester.c: Changed main() argv parameter type (Linux Warning generated) + * Added a WBXML Test File + * Making release v0.3 + +2002-06-29 Aymerick Jehanne + * Making release v0.2 + +2002-06-29 Aymerick Jehanne + * Added a Windows GUI. It seems to work.. it's late... and i go to bed... + +2002-06-28 Aymerick Jehanne + * Added 'extern "C"' in *.h files, so that we can use the library + in a C++ program. + +2002-06-19 Aymerick Jehanne + * Ho yes ! Now wbxmllib is accessible via SourceForge ! =) + +2002-06-15 Aymerick Jehanne + * First release of WBXML Library (v0.1) under LGPL 2.1 + It contains a WBXML Parser, with a SAX like interface. + + Known issues: + - Support of Charsets not fully implemented (we assume that strings + are NULL terminated). + - Only tested with WML Content. diff --git a/GNU-LGPL b/GNU-LGPL new file mode 100644 index 0000000..dc847af --- /dev/null +++ b/GNU-LGPL @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! \ No newline at end of file diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..2bdff6d --- /dev/null +++ b/INSTALL @@ -0,0 +1,78 @@ + WBXML Library INSTALLATION OVERVIEW + + Dependencies + ------------ + + The WBXML library needs the Expat XML Parser library to convert XML to WBXML + (http://expat.sourceforge.net) + + On Linux Debian, just type: + $ apt-get install libexpat1-dev + + Unix(Linux/FreeBSD/Solaris) + --------------------------- + + libwbxml is using CMake as "build environment" (http://www.cmake.org). + You must have cmake 2.4+. For example, on Debian: + $ apt-get install cmake + + We only support/test "out of source builds", which means you have to create a + separated build directory. + + Example 1: + + mkdir build + cd build + cmake -DCMAKE_INSTALL_PREFIX=$prefix /path/to/libwbxml/source/ + make + make test + make install + + Example 2: + + cd /path/to/libwbxml/source/ + cmake . -B/tmp/build/libwbxml + cd /tmp/build/libwbxml + make + make test + make install + + Windows + ------- + + The Win32 binary of Expat library is in: "/win32/expat" + + Just open the 'win32/libwbxml.dsw' VC++ workspace, and build: + + - libwbxml2.dll : Main WBXML engine - Parser and Encoder (needs Expat for XML to WBXML conversion) + - wbxml2xml.exe : WBXML to XML converter tool + - xml2wbxml.exe : XML to WBXML converter tool + + Symbian + ------- + + You must have the "Nokia S60 SDK v1.2" installed. + + You must have the Expat library (ported to Symbian) installed. + + Go to 'symbian/' folder and type: + c:\Symbian\libwbxml\symbian> bldmake bldfiles + c:\Symbian\libwbxml\symbian> abld build wins deb + + Compilation Flags + ----------------- + + WBXML_ENCODER_USE_STRTBL : Enable "String Table" code in WBXML Encoder + WBXML_SUPPORT_WML : Support of WML 1.0 / WML 1.1 / WML 1.2 / WML 1.3 + WBXML_SUPPORT_WTA : Support of WTA 1.0 / WTAWML 1.2 / CHANNEL 1.1 / CHANNEL 1.2 + WBXML_SUPPORT_SI : Support of SI 1.0 + WBXML_SUPPORT_SL : Support of SL 1.0 + WBXML_SUPPORT_CO : Support of CO 1.0 + WBXML_SUPPORT_PROV : Support of PROV 1.0 + WBXML_SUPPORT_EMN : Support of EMN 1.0 + WBXML_SUPPORT_DRMREL : Support of DRMREL 1.0 + WBXML_SUPPORT_OTA_SETTINGS : Support of Ericsson / Nokia OTA Settings v7.0 + WBXML_SUPPORT_SYNCML : Support of SyncML 1.0 / SyncML 1.1 / SyncML 1.2 + WBXML_SUPPORT_WV : Support of Wireless-Village CSP 1.1 / CSP 1.2 + + HAVE_EXPAT : Enable XML Parsing feature (needs Expat) diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..82f17bc --- /dev/null +++ b/MANIFEST @@ -0,0 +1,97 @@ +AUTHORS +BUGS +COPYING +ChangeLog +GNU-LGPL +INSTALL +MANIFEST +Makefile.am +NEWS +README +References +THANKS +TODO +bootstrap +configure.in +doxygen.h +libwbxml2.pc.in +macosx/expat/ascii.h +macosx/expat/asciitab.h +macosx/expat/expat.h +macosx/expat/expat_config.h +macosx/expat/iasciitab.h +macosx/expat/internal.h +macosx/expat/latin1tab.h +macosx/expat/nametab.h +macosx/expat/utf8tab.h +macosx/expat/xmlparse.c +macosx/expat/xmlrole.c +macosx/expat/xmlrole.h +macosx/expat/xmltok.c +macosx/expat/xmltok.h +macosx/expat/xmltok_impl.c +macosx/expat/xmltok_impl.h +macosx/expat/xmltok_ns.c +macosx/libwbxml.xcodeproj/project.pbxproj +src/Makefile.am +src/wbxml.h +src/wbxml_base64.c +src/wbxml_base64.h +src/wbxml_buffers.c +src/wbxml_buffers.h +src/wbxml_charset.c +src/wbxml_charset.h +src/wbxml_conv.c +src/wbxml_conv.h +src/wbxml_elt.c +src/wbxml_elt.h +src/wbxml_encoder.c +src/wbxml_encoder.h +src/wbxml_errors.c +src/wbxml_errors.h +src/wbxml_handlers.h +src/wbxml_lists.c +src/wbxml_lists.h +src/wbxml_log.c +src/wbxml_log.h +src/wbxml_mem.c +src/wbxml_mem.h +src/wbxml_parser.c +src/wbxml_parser.h +src/wbxml_tables.c +src/wbxml_tables.h +src/wbxml_tree.c +src/wbxml_tree.h +src/wbxml_tree_clb_wbxml.c +src/wbxml_tree_clb_wbxml.h +src/wbxml_tree_clb_xml.c +src/wbxml_tree_clb_xml.h +src/wbxml_wrap_syncml.c +src/wbxml_wrap_syncml.h +symbian/LIBWBXML_ARMI.DEF +symbian/LIBWBXML_WINS.DEF +symbian/bld.inf +symbian/libwbxml.mmp +symbian/libwbxmldll.cpp +symbian/wbxml2xml.mmp +symbian/xml2wbxml.mmp +tools/Makefile.am +tools/attgetopt.c +tools/getopt.h +tools/wbxml2xml_tool.c +tools/xml2wbxml_tool.c +wbxml2.spec.in +win32/expat/COPYING.txt +win32/expat/README.txt +win32/expat/expat.h +win32/expat/libexpat.dll +win32/expat/libexpat.lib +win32/leaktrack/COPYING.txt +win32/leaktrack/leaktrack.dll +win32/leaktrack/leaktrack.h +win32/leaktrack/leaktrack.lib +win32/leaktrack/lt_log.h +win32/libwbxml.dsw +win32/libwbxml2/libwbxml2.dsp +win32/wbxml2xml/wbxml2xml.dsp +win32/xml2wbxml/xml2wbxml.dsp diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..74493b0 --- /dev/null +++ b/NEWS @@ -0,0 +1,92 @@ +wxbml -- History of visible changes. + +Copyright (C) 2002-2008, Aymerick Jehanne +See the end for copying conditions. + +Please send wxbml bug reports to Aymerick Jehanne + +Version 0.9.3 + +* Features +- Project cleanup + +Version 0.9.2 + +* Features +- SyncML 1.2 +- New encoder 'flow mode' +- WBXMLTree API enhancements + +Version 0.9.1 + +* Features +- Nokia 6600 SyncML support + +Version 0.9.0 + +* Features +- New license: GNU GPL +- News website: http://libwbxml.aymerick.com +- Added CDATA Support +- Added Symbian Port + +Version 0.8.2 + +* Features +- Removed a major bug with SyncML support +- Last release before moving to 'happycoders.net' framework +- Last release under LGPL + +Version 0.8.2 + +* Features +- Removed a major bug with SyncML support +- Last release before moving to 'happycoders.net' framework +- Last release under LGPL + +Version 0.8.1 + +* Features +- Possibility to choose version of generated WBXML +- Improved DRMREL support +- Added Leak Tracker + +Version 0.8.0 + +* Features +- Code refacoring (no more 'libwbxml2_conv' library) +- Better SyncML support + +Version 0.7.2 + +* Features +- EMN 1.0 Support (tested) +- Prov 1.0 Support (tested) +- Wireless-Village CSP 1.1 / 1.2 Support (partially tested) +- Changed all End Of Line to "LF" (instead of "CR-LF") in all files +- Correction of bugs in String Table handling + +Version 0.7.0 + +* Features +- New wbxml2 branch + +Version 0.6.1 + +* Features +- libtoolized and autoconf + +Copying information: + +Copyright (C) 2002-2008, Aymerick Jehanne + + Permission is granted to anyone to make or distribute verbatim copies + of this document as received, in any medium, provided that the + copyright notice and this permission notice are preserved, + thus giving the recipient permission to redistribute in turn. + + Permission is granted to distribute modified versions + of this document, or of portions of it, + under the above conditions, provided also that they + carry prominent notices stating who last changed them. + diff --git a/README b/README new file mode 100644 index 0000000..e34f9a9 --- /dev/null +++ b/README @@ -0,0 +1,151 @@ + WBXML Library + ------------- + + The WBXML Library (aka libwbxml) contains a library and its associated tools to Parse, + Encode and Handle WBXML documents. + + The WBXML format is a binary representation of XML, defined by the Wap Forum, and used + to reduce bandwidth in mobile communications. + + + Dependency: + ----------- + + The WBXML Library needs Expat to enable XML Parsing feature (and so XML to WBXML conversion). + + + High Level API: + --------------- + + ------------------------- + (1) | | + [ WBXML ] ---------> | | ----------> [ XML ] + | WBXML Library | + [ WBXML ] <--------- | | <---------- [ XML ] + | | (2) + ------------------------- + + The high level API permits to: + - (1) Convert a WBXML Document to an XML Document + - (2) Convert an XML Document to a WBXML Document + + + Inside the WBXML Library: + ------------------------- + + [ WBXML ] [ XML ] + | | + | ------------------------- ----------------------- | + | | WBXML Parser (1) | | Expat XML Parser | | + | | | | | | + | ------------------------- ----------------------- | + | |WBXML Callbacks (3)| |XML Callbacks (4)| | + \ / + \ / + -------------------------> [ WBXML Tree (2) ] <------------------------ + + || + || + \/ + + ----------------------- + | WBXML Encoder (5) | + | | + ----------------------- + | | + | | + / \ + [ WBXML ] <----------------------- ------------------------> [ XML ] + + + The WBXML Library contains: + - (1) A WBXML Parser, with a SAX like interface (ie: this is a kind of Expat, but for WBXML) + - (2) A WBXML Tree structure (an internal representation of a WBXML/XML Document) + - (3) Libwbxml Callbacks to convert a WBXML Document to a WBXML Tree + - (4) Expat Callbacks to convert an XML Document to a WBXML Tree + - (5) A WBXML Encoder, that encodes a WBXML Tree to a WBXML Document or to an XML Document + + + If you find bugs, or simply use this library, feel free to contact me. + + + Supported Languages: + -------------------- + - WML 1.0, 1.1, 1.2, 1.3 + - WTA 1.0 + - WTA-WML 1.2 + - CHANNEL 1.1, 1.2 + - SI 1.0 (tested) + - SL 1.0 (tested) + - CO 1.0 + - PROV 1.0 (tested) + - EMN 1.0 (tested) + - DRMREL 1.0 (tested) + - Ericsson / Nokia OTA Settings v7.0 (tested) + - SYNCML 1.0, 1.1, 1.2 + - WV CSP 1.1, 1.2 (partially tested) + + + TOOLS: + ------ + + Two tools are provided: + - wbxml2xml: (WBXML => XML) + wbxml2xml -i -o output.xml input.wbxml + wbxml2xml -i 4 -l CSP12 -o output.xml input.wbxml + Options: + -o output.xml : output file + -m X (Generation mode - Default: 1) with: + 0: Compact Generation + 1: Indent Generation + 2: Canonical Generation + -i X (Indent delta when using mode '1' - Default: 1) + -k (Keep Ignorable Whitespaces - Default: FALSE) + -l X (Force Language Type of document to parse) + WML10 : WML 1.0 + WML11 : WML 1.1 + WML12 : WML 1.2 + WML13 : WML 1.3 + WTA10 : WTA 1.0 + WTAWML12 : WTAWML 1.2 + CHANNEL11 : CHANNEL 1.1 + CHANNEL12 : CHANNEL 1.2 + SI10 : SL 1.0 + SL10 : SI 1.0 + CO10 : CO 1.0 + PROV10 : PROV 1.0 + EMN10 : EMN 1.0 + DRMREL10 : DRMREL 1.0 + OTA : OTA Settings + SYNCML10 : SYNCML 1.0 + DEVINF10 : DEVINF 1.0 + SYNCML11 : SYNCML 1.1 + DEVINF11 : DEVINF 1.1 + METINF11 : METINF 1.1 + SYNCML12 : SYNCML 1.2 + DEVINF12 : DEVINF 1.2 + METINF12 : METINF 1.2 + CSP11 : WV CSP 1.1 + CSP12 : WV CSP 1.2 + Note: '-' can be used to mean stdin on input or stdout on output + + - xml2wbxml: (XML => WBXML) + xml2wbxml -o output.wbxml input.xml + xml2wbxml -k -n -v 1.1 -o output.wbxml input.xml + Options: + -o output.wbxml : output file + -k : keep ignorable whitespaces (Default: ignore) + -n : do NOT generate String Table (Default: generate) + -v X (WBXML Version of output document) + 1.0 : WBXML 1.0 + 1.1 : WBXML 1.1 + 1.2 : WBXML 1.2 + 1.3 : WBXML 1.3 + Note: '-' can be used to mean stdin on input or stdout on output + + + CONTACT: + -------- + + OpenSync mailing list + http://libwbxml.opensync.org diff --git a/RELEASE b/RELEASE new file mode 100644 index 0000000..ea058eb --- /dev/null +++ b/RELEASE @@ -0,0 +1,75 @@ +Making a release +================ + +To make a release of libwbxml, do the following: + + - check out a fresh copy from subversion + + - increment the version numbers in ./CMakeLists.txt: + + Package Version: + LIBWBXML_VERSION_MAJOR + LIBWBXML_VERSION_MINOR + LIBWBXML_VERSION_PATCH + + Library Version: + LIBWBXML_LIBVERSION_AGE + * Increment if any interface changed since last release. + + LIBWBXML_LIBVERSION_REVISION + * Increment if any library code changed since last release. + Set to 0 if any interface has been changed since last release. + + LIBWBXML_LIBVERSION_AGE + * Reset to 0 if any interface has been removed since last release. + If any interface has been added then increment. + + + - Run "make test" again several times to try to see race conditions. + "cd trunk" + "cmake . -B/tmp/build/libwbxml" + "cd /tmp/build/libwbxml" + "make" + "make test" + + - Commit the increased version changes (and build fixes) + + - if someone else made changes and the commit fails, + you have to "svn up" and run the tests again + + - please run "svn status" before you continue to be 100 percent sure + that there is no forgotten commit and no unrevisioned file. + + - please run 'find . -name "svn-commit*.tmp" -print' to detect + waste from failed commits. + + - once the commit succeeds, you have to create a new tag with + "mkdir tags/libwbxml-$MAJOR.$MINOR.$PATCH", + 'tar -C trunk --exclude="\.svn" -cf - . | tar -C tags/libwbxml-$MAJOR.$MINOR.$PATCH -xf -' + "svn add tags/libwbxml-$MAJOR.$MINOR.$PATCH" and + "svn commit tags/libwbxml-$MAJOR.$MINOR.$PATCH trunk" + (NEVER use "svn cp" because you must replace the external entities + of the trunk directory with hard copies of the actual state.) + + - create tarballs for an out-of-source-build with + "cmake tags/libwbxml-$MAJOR.$MINOR.$PATCH -B/tmp/build/libwbxml-$MAJOR.$MINOR.$PATCH", + "cd /tmp/build/libwbxml-$MAJOR.$MINOR.$PATCH", + "make package_source" + + - write checksums with md5sum from the tarballs to a file with the + same name like the tarballs without the tar and compression suffixes + and plus a new suffix md5sum + Example: + md5sum libwbxml-$MAJOR.$MINOR.$PATCH.tar.* > libwbxml-$MAJOR.$MINOR.$PATCH.md5sum + md5sum -c libwbxml-$MAJOR.$MINOR.$PATCH.md5sum + sha512sum libwbxml-$MAJOR.$MINOR.$PATCH.tar.* > libwbxml-$MAJOR.$MINOR.$PATCH.sha512sum + sha512sum -c libwbxml-$MAJOR.$MINOR.$PATCH.sha512sum + + - upload the tarballs and the checksum file to the File Release System + of SourceForge via the web interface + + - Annouce the release on the mailing list + Tips: + * make diff of the exported symbols "nm -g -P libwbxml.so" + * read svn log + * check trac tickets which are attached to the according milestone diff --git a/References b/References new file mode 100644 index 0000000..b191139 --- /dev/null +++ b/References @@ -0,0 +1,60 @@ +WAP Forum Specifications: (http://www.wapforum.org) +------------------------- +* WAP 1.0: + WBXML 1.0: WBXML-30-Apr-98.pdf + WML 1.0: WML-30-Apr-98.pdf + WTA 1.0: wta-30-apr-98.pdf + +* WAP 1.1: + WBXML 1.1: SPEC-WBXML-19990616.pdf + WML 1.1: SPEC-WML-19990616.pdf + CHANNEL 1.1: SPEC-WTA-19990716.pdf + +* WAP 1.2: + WBXML 1.2: SPEC-WBXML-19991104.pdf + WML 1.2: SPEC-WML-19991104.pdf + SI 1.0: WAP-167-ServiceInd-20010731-a.pdf + SL 1.0: WAP-168-ServiceLoad-20010731-a.pdf + +* WAP 1.2.1 (June 2000): + WBXML 1.3: WAP-192-WBXML-20010725-a.pdf + WBXML 1.3 SIN : WAP-192_105-WBXML-20011015-a.pdf + WML 1.3: WAP-191-WML-20000219-a.pdf + CO 1.0: WAP-175-CacheOp-20010731-a.pdf + +* WAP 2.0: + Prov 1.0 : WAP-183-PROVCONT-20010724-a.pdf + WTA WML1.2: WAP-266-WTA-20010908-a.pdf + CHANNEL 1.2: WAP-266-WTA-20010908-a.pdf + + +OMA Specifications: (http://www.openmobilealliance.org/) +------------------- +* WAP Provisioning 1.0: + OMA-WAP-ProvCont-v1_1-20021112-C.PDF + +* EMail Notification 1.0: + OMA-ERELD-EMN-V1_0-20021031-C.PDF + +* Rights Expression Language Version 1.0: + OMA-Download-DRMREL-v1_0-20020913-a.pdf + + +OMA SyncML Specifications: (http://www.openmobilealliance.org/tech/affiliates/syncml/syncmlindex.html) +-------------------------- +* SyncML 1.1.1: + syncml_represent_v111_20021002.pdf + syncml_metinf_v111_20021002.pdf + syncml_devinf_v111_20021002.pdf + +* SyncML 1.2: + ... + + +OMA Wireless-Village Specifications: (http://www.openmobilealliance.org/tech/affiliates/wv/wvindex.html) +------------------------------------ +* OMA Wireless-Village CSP 1.1 + OMA-WV-CSP_WBXML-V1_1-20021001-A.pdf + +* OMA Wireless-Village CSP 1.2 + OMA-IMPS-WV-CSP_WBXML-V1_2-20040522-C.pdf diff --git a/THANKS b/THANKS new file mode 100644 index 0000000..8b883fb --- /dev/null +++ b/THANKS @@ -0,0 +1,29 @@ +The original author of the library is: + +Aymerick Jehanne + +The actual maintainer of the library is: + +Michael Bell + +The following people helped to develop and maintain this library: + +Amnon Aaronsohn (ActiveSync) +Pau Aliagas +Michael Banck (Debian package maintainer, testing) +Michael Bell +Conrad Irwin (performance fixes) +Aymerick Jehanne +Ossi Jormakka (Ixonos Plc., ActiveSync) +Anton D. Kachalov (Nokia ConML support) +Benedykt Kroplewski +Jeremy Lainé (helped with cmake on Win32) +Mark Ostrer (Websense) +Petr Písař (RedHat/Fedora package maintainer) +Boaz Yaniv (MS Visual Studio fixes) + +If you think your name is missing here +then please feel free to create a ticket. +Such a ticket is no offence. +The missing name is an offence. + diff --git a/TODO b/TODO new file mode 100644 index 0000000..368f46a --- /dev/null +++ b/TODO @@ -0,0 +1,52 @@ +General +------- +- An automatic test tool + +Encoder: +- Parse and encode XML CDDATA +- Parse and encode XML PI +- Generate ENTITY tokens +- Handle Charsets Encoding +- UCS4 conversion + +Parser: +- Handle Charsets Encoding + + +WML 1.0 / WML 1.1 / WML 1.2 / WML 1.3 +------------------------------------- +- WML Test Suite + +Encoder: +- Check if there are variables: encode them in Extension Tokens +- Check if we must keep Ignorable Whitespaces (in WML, if we are in a
, we MUST keep this spaces)
+
+
+WTA 1.0
+-------
+- WTA Test Suite
+
+
+CO 1.0
+------
+- CO Test Suite
+
+
+CHANNEL 1.1 / CHANNEL 1.2
+-------------------------
+- Channel Test Suite
+
+
+WTA-WML 1.2
+-----------
+- WTA-WML Test Suite
+
+
+SYNCML 1.1 / 1.2
+----------------
+- Real SyncML Support (testing with real devices/servers)
+
+
+WV CSP 1.1
+----------
+- Encode Date and Time in OPAQUE (WV_CSP_WBXML_v1.1.pdf - 4.6)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
new file mode 100644
index 0000000..f2c136b
--- /dev/null
+++ b/cmake/CMakeLists.txt
@@ -0,0 +1,5 @@
+
+SET( LIBWBXML_CMAKE_MODULE "${CMAKE_CURRENT_SOURCE_DIR}/modules/FindLibWbxml2.cmake" )
+
+INSTALL( FILES ${LIBWBXML_CMAKE_MODULE} DESTINATION ${CMAKE_ROOT}/Modules/ )
+
diff --git a/cmake/modules/AddDocumentation.cmake b/cmake/modules/AddDocumentation.cmake
new file mode 100644
index 0000000..680d6c9
--- /dev/null
+++ b/cmake/modules/AddDocumentation.cmake
@@ -0,0 +1,76 @@
+# - InstallDocumentation.cmake
+# Installs different types of documentation
+#
+# Copyright (c) 2008 Michael Bell  
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( Documentation )
+
+SET( SHARE_INSTALL_DIR    "${CMAKE_INSTALL_PREFIX}/share" CACHE INTERNAL "share location" )
+SET( DOC_MAN_INSTALL_DIR  "${SHARE_INSTALL_DIR}/man" CACHE INTERNAL "man page location" )
+SET( DOC_INSTALL_DIR      "${SHARE_INSTALL_DIR}/doc/${PROJECT_NAME}" CACHE INTERNAL "documentation location" )
+SET( DOC_TEXT_INSTALL_DIR "${DOC_INSTALL_DIR}" CACHE INTERNAL "text documentation location" )
+SET( DOC_HTML_INSTALL_DIR "${DOC_INSTALL_DIR}/html" CACHE INTERNAL "HTML documentation location" )
+
+MACRO( ADD_DOCUMENTATION _formatName _fileType )
+
+	# _formatName - HTML, TEXT, MAN
+	# _fileType   - DIRECTORY, FILE
+	# ARGN        - filenames
+
+	# check _formatName
+
+	STRING( TOUPPER ${_formatName} FORMAT_NAME )
+	STRING( COMPARE EQUAL ${FORMAT_NAME} "HTML" FORMAT_IS_HTML )
+	STRING( COMPARE EQUAL ${FORMAT_NAME} "TEXT" FORMAT_IS_TEXT )
+	STRING( COMPARE EQUAL ${FORMAT_NAME} "MAN" FORMAT_IS_MAN )
+	IF( NOT ${FORMAT_IS_HTML} AND NOT ${FORMAT_IS_TEXT} AND NOT ${FORMAT_IS_MAN} )
+		MESSAGE( SEND_ERROR "ADD_DOCUMENTATION only support HTML, TEXT and MAN as formats." )
+		RETURN()
+	ENDIF( NOT ${FORMAT_IS_HTML} AND NOT ${FORMAT_IS_TEXT} AND NOT ${FORMAT_IS_MAN} )
+
+	# check _fileType
+
+	STRING( TOUPPER ${_fileType} FILE_TYPE )
+	STRING( COMPARE EQUAL ${FILE_TYPE} "DIRECTORY" FILE_IS_DIRECTORY )
+	STRING( COMPARE EQUAL ${FILE_TYPE} "FILE" FILE_IS_FILE )
+	IF( NOT ${FILE_IS_DIRECTORY} AND NOT ${FILE_IS_FILE} )
+		MESSAGE( SEND_ERROR "ADD_DOCUMENTATION only support DIRECTORY and FILE as file types." )
+		RETURN()
+	ENDIF( NOT ${FILE_IS_DIRECTORY} AND NOT ${FILE_IS_FILE} )
+
+	# install HTML documenation
+
+	IF( ${FORMAT_IS_HTML} )
+		IF( ${FILE_IS_DIRECTORY} )
+			INSTALL( DIRECTORY ${ARGN} DESTINATION ${DOC_HTML_INSTALL_DIR} )
+		ELSE( ${FILE_IS_DIRECTORY} )
+			INSTALL( FILES ${ARGN} DESTINATION ${DOC_HTML_INSTALL_DIR} )
+		ENDIF( ${FILE_IS_DIRECTORY} )
+	ENDIF( ${FORMAT_IS_HTML} )
+
+	# install TEXT documenation
+
+	IF( ${FORMAT_IS_TEXT} )
+		IF( ${FILE_IS_DIRECTORY} )
+			INSTALL( DIRECTORY ${ARGN} DESTINATION ${DOC_TEXT_INSTALL_DIR} )
+		ELSE( ${FILE_IS_DIRECTORY} )
+			INSTALL( FILES ${ARGN} DESTINATION ${DOC_TEXT_INSTALL_DIR} )
+		ENDIF( ${FILE_IS_DIRECTORY} )
+	ENDIF( ${FORMAT_IS_TEXT} )
+
+	# install man pages
+
+	IF( ${FORMAT_IS_MAN} )
+		IF( ${FILE_IS_DIRECTORY} )
+			INSTALL( DIRECTORY ${ARGN} DESTINATION ${DOC_MAN_INSTALL_DIR} )
+		ELSE( ${FILE_IS_DIRECTORY} )
+			INSTALL( FILES ${ARGN} DESTINATION ${DOC_MAN_INSTALL_DIR} )
+		ENDIF( ${FILE_IS_DIRECTORY} )
+	ENDIF( ${FORMAT_IS_MAN} )
+
+ENDMACRO( ADD_DOCUMENTATION _formatName _fileType )
diff --git a/cmake/modules/COPYING-CMAKE-SCRIPTS b/cmake/modules/COPYING-CMAKE-SCRIPTS
new file mode 100644
index 0000000..53b6b71
--- /dev/null
+++ b/cmake/modules/COPYING-CMAKE-SCRIPTS
@@ -0,0 +1,22 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/cmake/modules/Compiler.cmake b/cmake/modules/Compiler.cmake
new file mode 100644
index 0000000..fc557b1
--- /dev/null
+++ b/cmake/modules/Compiler.cmake
@@ -0,0 +1,25 @@
+# Copyright (c) 2007 Daniel Gollub 
+
+IF ( CMAKE_COMPILER_IS_GNUCC )
+  SET( SYMBOLS_VISIBILITY "-fvisibility=hidden" )
+  SET( CMAKE_C_FLAGS_HACKING "-O2 -fmessage-length=0 -Wall -Werror -D_FORTIFY_SOURCE=2 -fstack-protector -g" CACHE STRING "Developer C Compiler Flags" )
+  SET( CMAKE_CXX_FLAGS_HACKING "-O2 -fmessage-length=0 -Wall -Werror -D_FORTIFY_SOURCE=2 -fstack-protector -g" CACHE STRING "Developer C++ Compiler Flags" )
+ENDIF ( CMAKE_COMPILER_IS_GNUCC )
+
+IF (CMAKE_SYSTEM MATCHES "SunOS-5*.")
+  SET( SYMBOLS_VISIBILITY "-xldscope=hidden" )
+ENDIF (CMAKE_SYSTEM MATCHES "SunOS-5*.")
+
+IF ( SYMBOLS_VISIBILITY )
+  INCLUDE( CheckCCompilerFlag )
+  check_c_compiler_flag( ${SYMBOLS_VISIBILITY} COMPILER_SUPPORTS_VISIBILITY )
+ENDIF ( SYMBOLS_VISIBILITY )
+
+IF (NOT COMPILER_SUPPORTS_VISIBILITY)
+  SET( SYMBOLS_VISIBILITY "" )
+ENDIF (NOT COMPILER_SUPPORTS_VISIBILITY)
+
+IF ( MSVC )
+  # Some compiler options for MSVC to not print non-sense warnings.
+  ADD_DEFINITIONS ( -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE )
+ENDIF ( MSVC )
diff --git a/cmake/modules/FindBONOBO2.cmake b/cmake/modules/FindBONOBO2.cmake
new file mode 100644
index 0000000..2c75b15
--- /dev/null
+++ b/cmake/modules/FindBONOBO2.cmake
@@ -0,0 +1,115 @@
+# - Try to find bonobo2 
+# Find bonobo2 headers, libraries and the answer to all questions.
+#
+#  BONOBO2_FOUND               True if bonobo2 got found
+#  BONOBO2_INCLUDEDIR          Location of bonobo2 headers 
+#  BONOBO2_LIBRARIES           List of libaries to use bonobo2
+#  BONOBO2_DEFINITIONS         Definitions to compile bonobo2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+
+
+INCLUDE( FindPkgConfig )
+# Take care about libbonobo-2.0.pc settings
+IF ( BONOBO2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( BONOBO2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( BONOBO2_FIND_REQUIRED )
+
+IF ( BONOBO2_MIN_VERSION )
+	pkg_search_module( BONOBO2 ${_pkgconfig_REQUIRED} libbonobo-2.0>=${BONOBO2_MIN_VERSION} )
+ELSE ( BONOBO2_MIN_VERSION )
+	pkg_search_module( BONOBO2 ${_pkgconfig_REQUIRED} libbonobo-2.0 )
+ENDIF ( BONOBO2_MIN_VERSION )
+
+
+# Look for libbonobo2 include dir and libraries w/o pkgconfig
+IF ( NOT BONOBO2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _bonobo2_include_DIR libbonobo.h PATH_SUFFIXES libbonobo-2.0 
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+	)
+	FIND_LIBRARY( _bonobo2_link_DIR bonobo-2 
+		PATHS
+		/opt/local/lib
+		/sw/lib
+		/usr/lib
+		/usr/local/lib
+		/usr/lib64
+		/usr/local/lib64
+		/opt/lib64
+	)
+	IF ( _bonobo2_include_DIR AND _bonobo2_link_DIR )
+		SET ( _bonobo2_FOUND TRUE )
+	ENDIF ( _bonobo2_include_DIR AND _bonobo2_link_DIR )
+
+
+	IF ( _bonobo2_FOUND )
+		SET ( BONOBO2_INCLUDE_DIRS ${_bonobo2_include_DIR} )
+		SET ( BONOBO2_LIBRARIES ${_bonobo2_link_DIR} )
+	ENDIF ( _bonobo2_FOUND )
+
+	# Handle dependencies
+	IF ( NOT BONOBOACTIVATION2_FOUND )
+		FIND_PACKAGE( BONOBOACTIVATION2 REQUIRED)
+		IF ( BONOBOACTIVATION2_FOUND )
+			SET ( BONOBO2_INCLUDE_DIRS ${BONOBO2_INCLUDE_DIRS} ${BONOBOACTIVATION2_INCLUDE_DIRS} )
+			SET ( BONOBO2_LIBRARIES ${BONOBO2_LIBRARIES} ${BONOBOACTIVATION2_LIBRARIES} )
+		ENDIF ( BONOBOACTIVATION2_FOUND )
+	ENDIF ( NOT BONOBOACTIVATION2_FOUND )
+	IF ( NOT ORBIT2_FOUND )
+		FIND_PACKAGE( ORBit2 REQUIRED)
+		IF ( ORBIT2_FOUND )
+			SET ( BONOBO2_INCLUDE_DIRS ${BONOBO2_INCLUDE_DIRS} ${ORBIT2_INCLUDE_DIRS} )
+			SET ( BONOBO2_LIBRARIES ${BONOBO2_LIBRARIES} ${ORBIT2_LIBRARIES} )
+		ENDIF ( ORBIT2_FOUND )
+	ENDIF ( NOT ORBIT2_FOUND )
+        IF ( NOT GLIB2_FOUND )
+                FIND_PACKAGE( GLIB2 REQUIRED)
+
+                IF ( GMODULE2_FOUND )
+                        SET ( BONOBO2_INCLUDE_DIRS ${BONOBO2_INCLUDE_DIRS} ${GMODULE2_INCLUDE_DIR} )
+                        SET ( BONOBO2_LIBRARIES ${BONOBO2_LIBRARIES} ${GMODULE2_LIBRARY} )
+                ENDIF ( GMODULE2_FOUND )
+                IF ( GLIB2_FOUND )
+                        SET ( BONOBO2_INCLUDE_DIRS ${BONOBO2_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIR} ${GLIBCONFIG_INCLUDE_DIR} )
+                        SET ( BONOBO2_LIBRARIES ${BONOBO2_LIBRARIES} ${GLIB2_LIBRARY} )
+                ENDIF ( GLIB2_FOUND )
+        ENDIF ( NOT GLIB2_FOUND )
+
+
+
+	# Report results
+	IF ( BONOBO2_LIBRARIES AND BONOBO2_INCLUDE_DIRS AND _bonobo2_FOUND )	
+		SET( BONOBO2_FOUND 1 )
+		IF ( NOT BONOBO2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found bonobo2: ${BONOBO2_LIBRARIES} ${BONOBO2_INCLUDE_DIRS}" )
+		ENDIF ( NOT BONOBO2_FIND_QUIETLY )
+	ELSE ( BONOBO2_LIBRARIES AND BONOBO2_INCLUDE_DIRS AND _bonobo2_FOUND )	
+		IF ( BONOBO2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find bonobo2" )
+		ELSE ( BONOBO2_FIND_REQUIRED )
+			IF ( NOT BONOBO2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find bonobo2" )	
+			ENDIF ( NOT BONOBO2_FIND_QUIETLY )
+		ENDIF ( BONOBO2_FIND_REQUIRED )
+	ENDIF ( BONOBO2_LIBRARIES AND BONOBO2_INCLUDE_DIRS AND _bonobo2_FOUND )	
+
+ENDIF ( NOT BONOBO2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( BONOBO2_LIBRARIES BONOBO2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindBONOBOACTIVATION2.cmake b/cmake/modules/FindBONOBOACTIVATION2.cmake
new file mode 100644
index 0000000..fa87316
--- /dev/null
+++ b/cmake/modules/FindBONOBOACTIVATION2.cmake
@@ -0,0 +1,112 @@
+# - Try to find bonobo-activation-2 
+# Find bonobo-activation-2 headers, libraries and the answer to all questions.
+#
+#  BONOBOACTIVATION2_FOUND               True if bonobo-activation-2 got found
+#  BONOBOACTIVATION2_INCLUDEDIR          Location of bonobo-activation-2 headers 
+#  BONOBOACTIVATION2_LIBRARIES           List of libaries to use bonobo-activation-2
+#  BONOBOACTIVATION2_DEFINITIONS         Definitions to compile bonobo-activation-2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+
+
+
+
+
+
+INCLUDE( FindPkgConfig )
+# Take care about bonobo-activation-2.0.pc settings
+IF ( BONOBOACTIVATION2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( BONOBOACTIVATION2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( BONOBOACTIVATION2_FIND_REQUIRED )
+
+IF ( BONOBOACTIVATION2_MIN_VERSION )
+	pkg_search_module( BONOBOACTIVATION2 ${_pkgconfig_REQUIRED} bonobo-activation-2.0>=${BONOBOACTIVATION2_MIN_VERSION} )
+ELSE ( BONOBOACTIVATION2_MIN_VERSION )
+	pkg_search_module( BONOBOACTIVATION2 ${_pkgconfig_REQUIRED} bonobo-activation-2.0 )
+ENDIF ( BONOBOACTIVATION2_MIN_VERSION )
+
+
+# Look for bonoboactivation2 include dir and libraries w/o pkgconfig
+IF ( NOT BONOBOACTIVATION2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _bonoboactivation2_include_DIR bonobo-activation/bonobo-activation.h PATH_SUFFIXES bonobo-activation-2.0 
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+	)
+	FIND_LIBRARY( _bonoboactivation2_link_DIR bonobo-activation 
+		PATHS
+		/opt/local/lib
+		/sw/lib
+		/usr/lib
+		/usr/local/lib
+		/usr/lib64
+		/usr/local/lib64
+		/opt/lib64
+	)
+
+	IF ( _bonoboactivation2_include_DIR AND _bonoboactivation2_link_DIR )
+		SET ( _bonoboactivation2_FOUND TRUE )
+	ENDIF ( _bonoboactivation2_include_DIR AND _bonoboactivation2_link_DIR )
+
+
+	IF ( _bonoboactivation2_FOUND )
+		SET ( BONOBOACTIVATION2_INCLUDE_DIRS ${_bonoboactivation2_include_DIR} )
+		SET ( BONOBOACTIVATION2_LIBRARIES ${_bonoboactivation2_link_DIR} )
+	ENDIF ( _bonoboactivation2_FOUND )
+
+	# Handle dependencies
+	IF ( NOT ORBIT2_FOUND )
+		FIND_PACKAGE( ORBit2 REQUIRED)
+		IF ( ORBIT2_FOUND )
+			SET ( BONOBOACTIVATION2_INCLUDE_DIRS ${BONOBOACTIVATION2_INCLUDE_DIRS} ${ORBIT2_INCLUDE_DIRS} )
+			SET ( BONOBOACTIVATION2_LIBRARIES ${BONOBOACTIVATION2_LIBRARIES} ${ORBIT2_LIBRARIES} )
+		ENDIF ( ORBIT2_FOUND )
+	ENDIF ( NOT ORBIT2_FOUND )
+        IF ( NOT GLIB2_FOUND )
+                FIND_PACKAGE( GLIB2 REQUIRED)
+
+                IF ( GMODULE2_FOUND )
+                        SET ( BONOBOACTIVATION2_INCLUDE_DIRS ${BONOBOACTIVATION2_INCLUDE_DIRS} ${GMODULE2_INCLUDE_DIR} )
+                        SET ( BONOBOACTIVATION2_LIBRARIES ${BONOBOACTIVATION2_LIBRARIES} ${GMODULE2_LIBRARY} )
+                ENDIF ( GMODULE2_FOUND )
+                IF ( GLIB2_FOUND )
+                        SET ( BONOBOACTIVATION2_INCLUDE_DIRS ${BONOBOACTIVATION2_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIR} ${GLIBCONFIG_INCLUDE_DIR} )
+                        SET ( BONOBOACTIVATION2_LIBRARIES ${BONOBOACTIVATION2_LIBRARIES} ${GLIB2_LIBRARY} )
+                ENDIF ( GLIB2_FOUND )
+        ENDIF ( NOT GLIB2_FOUND )
+
+
+	# Report results
+	IF ( BONOBOACTIVATION2_LIBRARIES AND BONOBOACTIVATION2_INCLUDE_DIRS AND _bonoboactivation2_FOUND )	
+		SET( BONOBOACTIVATION2_FOUND 1 )
+		IF ( NOT BONOBOACTIVATION2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found bonobo-activation2: ${BONOBOACTIVATION2_LIBRARIES} ${BONOBOACTIVATION2_INCLUDE_DIRS}" )
+		ENDIF ( NOT BONOBOACTIVATION2_FIND_QUIETLY )
+	ELSE ( BONOBOACTIVATION2_LIBRARIES AND BONOBOACTIVATION2_INCLUDE_DIRS AND _bonoboactivation2_FOUND )	
+		IF ( BONOBOACTIVATION2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find bonobo-activation2" )
+		ELSE ( BONOBOACTIVATION2_FIND_REQUIRED )
+			IF ( NOT BONOBOACTIVATION2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find bonobo-activation2" )	
+			ENDIF ( NOT BONOBOACTIVATION2_FIND_QUIETLY )
+		ENDIF ( BONOBOACTIVATION2_FIND_REQUIRED )
+	ENDIF ( BONOBOACTIVATION2_LIBRARIES AND BONOBOACTIVATION2_INCLUDE_DIRS AND _bonoboactivation2_FOUND )	
+
+ENDIF ( NOT BONOBOACTIVATION2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( BONOBOACTIVATION2_LIBRARIES BONOBOACTIVATION2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindBlueZ.cmake b/cmake/modules/FindBlueZ.cmake
new file mode 100644
index 0000000..8284380
--- /dev/null
+++ b/cmake/modules/FindBlueZ.cmake
@@ -0,0 +1,57 @@
+# - Try to find BlueZ
+# Find BlueZ headers, libraries and the answer to all questions.
+#
+#  BLUEZ_FOUND               True if BlueZ libraries got found
+#  BLUEZ_INCLUDE_DIRS         Location of BlueZ headers 
+#  BLUEZ_LIBRARIES           List of libaries to use BlueZ
+#
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007-2009 Bjoern Ricks  
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+# Take care about bluez.pc settings
+IF ( BlueZ_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( BlueZ_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( BlueZ_FIND_REQUIRED )
+
+IF ( BLUEZ_MIN_VERSION )
+	PKG_SEARCH_MODULE( BLUEZ ${_pkgconfig_REQUIRED} bluez>=${BLUEZ_MIN_VERSION} )
+ELSE ( BLUEZ_MIN_VERSION )
+	PKG_SEARCH_MODULE( BLUEZ ${_pkgconfig_REQUIRED} bluez )
+ENDIF ( BLUEZ_MIN_VERSION )
+
+# Look for BlueZ include dir and libraries
+IF( NOT BLUEZ_FOUND AND NOT PKG_CONFIG_FOUND )
+
+	FIND_PATH( BLUEZ_INCLUDE_DIRS bluetooth/bluetooth.h )
+	FIND_LIBRARY( BLUEZ_LIBRARIES bluetooth )
+
+	# Report results
+	IF ( BLUEZ_LIBRARIES AND BLUEZ_INCLUDE_DIRS )	
+		SET( BLUEZ_FOUND 1 )
+		IF ( NOT BlueZ_FIND_QUIETLY )
+			MESSAGE( STATUS "Found BlueZ: ${BLUEZ_LIBRARIES}" )
+		ENDIF ( NOT BlueZ_FIND_QUIETLY )
+	ELSE ( BLUEZ_LIBRARIES AND BLUEZ_INCLUDE_DIRS )	
+		IF ( BlueZ_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find BLUEZ" )
+		ELSE ( BlueZ_FIND_REQUIRED )
+			IF ( NOT BlueZ_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find BLUEZ" )	
+			ENDIF ( NOT BlueZ_FIND_QUIETLY )
+		ENDIF ( BlueZ_FIND_REQUIRED )
+	ENDIF ( BLUEZ_LIBRARIES AND BLUEZ_INCLUDE_DIRS )
+
+ENDIF( NOT BLUEZ_FOUND AND NOT PKG_CONFIG_FOUND  )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( BLUEZ_LIBRARIES BLUEZ_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindCheck.cmake b/cmake/modules/FindCheck.cmake
new file mode 100644
index 0000000..c25ac03
--- /dev/null
+++ b/cmake/modules/FindCheck.cmake
@@ -0,0 +1,55 @@
+# - Try to find the CHECK libraries
+#  Once done this will define
+#
+#  CHECK_FOUND - system has check
+#  CHECK_INCLUDE_DIRS - the check include directory
+#  CHECK_LIBRARIES - check library
+#  
+#  Copyright (c) 2007 Daniel Gollub 
+#  Copyright (c) 2007-2009 Bjoern Ricks  
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+INCLUDE( FindPkgConfig )
+
+IF ( Check_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( Check_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( Check_FIND_REQUIRED )
+
+IF ( CHECK_MIN_VERSION )
+	PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check>=${CHECK_MIN_VERSION} )
+ELSE ( CHECK_MIN_VERSION )
+	PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check )
+ENDIF ( CHECK_MIN_VERSION )
+
+# Look for CHECK include dir and libraries
+IF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND )
+
+	FIND_PATH( CHECK_INCLUDE_DIRS check.h )
+
+	FIND_LIBRARY( CHECK_LIBRARIES NAMES check )
+
+	IF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES )
+		SET( CHECK_FOUND 1 )
+		IF ( NOT Check_FIND_QUIETLY )
+			MESSAGE ( STATUS "Found CHECK: ${CHECK_LIBRARIES}" )
+		ENDIF ( NOT Check_FIND_QUIETLY )
+	ELSE ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES )
+		IF ( Check_FIND_REQUIRED )
+			MESSAGE( FATAL_ERROR "Could NOT find CHECK" )
+		ELSE ( Check_FIND_REQUIRED )
+			IF ( NOT Check_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find CHECK" )	
+			ENDIF ( NOT Check_FIND_QUIETLY )
+		ENDIF ( Check_FIND_REQUIRED )
+	ENDIF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES )
+ENDIF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( CHECK_INCLUDE_DIRS CHECK_LIBRARIES )
+
diff --git a/cmake/modules/FindEBook1.0.cmake b/cmake/modules/FindEBook1.0.cmake
new file mode 100644
index 0000000..98c75ed
--- /dev/null
+++ b/cmake/modules/FindEBook1.0.cmake
@@ -0,0 +1,102 @@
+# - Try to find libebook1.0 components
+# Find libebook 1.0 headers, libraries and the answer to all questions.
+#
+#  LIBEBOOK1.0_FOUND               True if libebook1.0 got found
+#  LIBEBOOK1.0_INCLUDE_DIRS         Location of libebook1.0 headers 
+#  LIBEBOOK1.0_LIBRARIES           List of libaries to use libebook1.0
+#  LIBEBOOK1.0_DEFINITIONS         Definitions to compile libebook1.0 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libebook-1.0.pc settings
+IF ( EBook1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( EBook1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( EBook1.0_FIND_REQUIRED )
+
+pkg_search_module( LIBEBOOK1.0 ${_pkgconfig_REQUIRED} libebook-1.0 )
+
+
+# Look for libebook1.0 include dir and libraries w/o pkg-config.
+IF ( NOT LIBEBOOK1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libebook1.0_include_DIR libebook/e-book.h 
+			PATH_SUFFIXES evolution-data-server-1.12 evolution-data-server-1.10 evolution-data-server-1.8 evolution-data-server-1.6 evolution-data-server-1.4 evolution-data-server-1.0
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+	FIND_LIBRARY( _libebook1.0_link_DIR ebook-1.0
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+        IF ( _libebook1.0_include_DIR AND _libebook1.0_link_DIR )
+                SET ( _libebook1.0_FOUND TRUE )
+        ENDIF ( _libebook1.0_include_DIR AND _libebook1.0_link_DIR )
+
+
+        IF ( _libebook1.0_FOUND )
+                SET ( LIBEBOOK1.0_INCLUDE_DIRS ${_libebook1.0_include_DIR} )
+                SET ( LIBEBOOK1.0_LIBRARIES ${_libebook1.0_link_DIR} )
+        ENDIF ( _libebook1.0_FOUND )
+
+        # Handle dependencies
+	IF ( NOT LIBEDATASERVER1.0_FOUND )
+		FIND_PACKAGE ( EDataServer1.0 REQUIRED )
+                IF ( LIBEDATASERVER1.0_FOUND )
+                        SET ( LIBEBOOK1.0_INCLUDE_DIRS ${LIBEBOOK1.0_INCLUDE_DIRS} ${LIBEDATASERVER1.0_INCLUDE_DIRS} )
+                        SET ( LIBEBOOK1.0_LIBRARIES ${LIBEBOOK1.0_LIBRARIES} ${LIBEDATASERVER1.0_LIBRARIES} )
+                ENDIF ( LIBEDATASERVER1.0_FOUND )		
+	ENDIF ( NOT LIBEDATASERVER1.0_FOUND )
+	IF ( NOT LIBGNOME2_FOUND )
+		FIND_PACKAGE ( LibGnome2 REQUIRED )
+                IF ( LIBGNOME2_FOUND )
+                        SET ( LIBEBOOK1.0_INCLUDE_DIRS ${LIBEBOOK1.0_INCLUDE_DIRS} ${LIBGNOME2_INCLUDE_DIRS} )
+                        SET ( LIBEBOOK1.0_LIBRARIES ${LIBEBOOK1.0_LIBRARIES} ${LIBGNOME2_LIBRARIES} )
+                ENDIF ( LIBGNOME2_FOUND )		
+	ENDIF ( NOT LIBGNOME2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( LIBEBOOK1.0_INCLUDE_DIRS ${LIBEBOOK1.0_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( LIBEBOOK1.0_LIBRARIES ${LIBEBOOK1.0_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+
+	# Report results
+	IF ( LIBEBOOK1.0_LIBRARIES AND LIBEBOOK1.0_INCLUDE_DIRS AND _libebook1.0_FOUND )
+		SET( LIBEBOOK1.0_FOUND 1 )
+		IF ( NOT EBook1.0_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libebook-1.0: ${LIBEBOOK1.0_LIBRARIES}" )
+		ENDIF ( NOT EBook1.0_FIND_QUIETLY )
+	ELSE ( LIBEBOOK1.0_LIBRARIES AND LIBEBOOK1.0_INCLUDE_DIRS AND _libebook1.0_FOUND )	
+		IF ( EBook1.0_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libebook-1.0" )
+		ELSE ( EBook1.0_FIND_REQUIRED )
+			IF ( NOT EBook1.0_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libebook-1.0" )	
+			ENDIF ( NOT EBook1.0_FIND_QUIETLY )
+		ENDIF ( EBook1.0_FIND_REQUIRED )
+	ENDIF ( LIBEBOOK1.0_LIBRARIES AND LIBEBOOK1.0_INCLUDE_DIRS AND _libebook1.0_FOUND )	
+
+ENDIF ( NOT LIBEBOOK1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBEBOOK1.0_LIBRARIES LIBEBOOK1.0_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindEBook1.2.cmake b/cmake/modules/FindEBook1.2.cmake
new file mode 100644
index 0000000..7496de3
--- /dev/null
+++ b/cmake/modules/FindEBook1.2.cmake
@@ -0,0 +1,103 @@
+# - Try to find libebook1.2 components
+# Find libebook 1.2 headers, libraries and the answer to all questions.
+#
+#  LIBEBOOK1.2_FOUND               True if libebook1.2 got found
+#  LIBEBOOK1.2_INCLUDE_DIRS         Location of libebook1.2 headers 
+#  LIBEBOOK1.2_LIBRARIES           List of libaries to use libebook1.2
+#  LIBEBOOK1.2_DEFINITIONS         Definitions to compile libebook1.2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libebook-1.2.pc settings
+IF ( EBook1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( EBook1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( EBook1.2_FIND_REQUIRED )
+
+pkg_search_module( LIBEBOOK1.2 ${_pkgconfig_REQUIRED} libebook-1.2 )
+
+
+# Look for libebook1.2 include dir and libraries w/o pkg-config.
+IF ( NOT LIBEBOOK1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libebook1.2_include_DIR libebook/e-book.h 
+			PATH_SUFFIXES evolution-data-server-1.12 evolution-data-server-1.10 evolution-data-server-1.8 evolution-data-server-1.6 evolution-data-server-1.4 evolution-data-server-1.2
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+	FIND_LIBRARY( _libebook1.2_link_DIR ebook-1.2
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+        IF ( _libebook1.2_include_DIR AND _libebook1.2_link_DIR )
+                SET ( _libebook1.2_FOUND TRUE )
+        ENDIF ( _libebook1.2_include_DIR AND _libebook1.2_link_DIR )
+
+
+        IF ( _libebook1.2_FOUND )
+                SET ( LIBEBOOK1.2_INCLUDE_DIRS ${_libebook1.2_include_DIR} )
+                SET ( LIBEBOOK1.2_LIBRARIES ${_libebook1.2_link_DIR} )
+        ENDIF ( _libebook1.2_FOUND )
+
+        # Handle dependencies
+	IF ( NOT LIBEDATASERVER1.2_FOUND )
+		FIND_PACKAGE ( EDataServer1.2 REQUIRED )
+                IF ( LIBEDATASERVER1.2_FOUND )
+                        SET ( LIBEBOOK1.2_INCLUDE_DIRS ${LIBEBOOK1.2_INCLUDE_DIRS} ${LIBEDATASERVER1.2_INCLUDE_DIRS} )
+                        SET ( LIBEBOOK1.2_LIBRARIES ${LIBEBOOK1.2_LIBRARIES} ${LIBEDATASERVER1.2_LIBRARIES} )
+                ENDIF ( LIBEDATASERVER1.2_FOUND )		
+	ENDIF ( NOT LIBEDATASERVER1.2_FOUND )
+	IF ( NOT LIBGNOME2_FOUND )
+		FIND_PACKAGE ( LibGnome2 REQUIRED )
+                IF ( LIBGNOME2_FOUND )
+                        SET ( LIBEBOOK1.2_INCLUDE_DIRS ${LIBEBOOK1.2_INCLUDE_DIRS} ${LIBGNOME2_INCLUDE_DIRS} )
+                        SET ( LIBEBOOK1.2_LIBRARIES ${LIBEBOOK1.2_LIBRARIES} ${LIBGNOME2_LIBRARIES} )
+                ENDIF ( LIBGNOME2_FOUND )		
+	ENDIF ( NOT LIBGNOME2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		SET ( BONOBO2_MIN_VERSION "2.4.2" )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( LIBEBOOK1.2_INCLUDE_DIRS ${LIBEBOOK1.2_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( LIBEBOOK1.2_LIBRARIES ${LIBEBOOK1.2_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+
+	# Report results
+	IF ( LIBEBOOK1.2_LIBRARIES AND LIBEBOOK1.2_INCLUDE_DIRS AND _libebook1.2_FOUND )
+		SET( LIBEBOOK1.2_FOUND 1 )
+		IF ( NOT EBook1.2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libebook-1.2: ${LIBEBOOK1.2_LIBRARIES}" )
+		ENDIF ( NOT EBook1.2_FIND_QUIETLY )
+	ELSE ( LIBEBOOK1.2_LIBRARIES AND LIBEBOOK1.2_INCLUDE_DIRS AND _libebook1.2_FOUND )	
+		IF ( EBook1.2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libebook-1.2" )
+		ELSE ( EBook1.2_FIND_REQUIRED )
+			IF ( NOT EBook1.2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libebook-1.2" )	
+			ENDIF ( NOT EBook1.2_FIND_QUIETLY )
+		ENDIF ( EBook1.2_FIND_REQUIRED )
+	ENDIF ( LIBEBOOK1.2_LIBRARIES AND LIBEBOOK1.2_INCLUDE_DIRS AND _libebook1.2_FOUND )	
+
+ENDIF ( NOT LIBEBOOK1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBEBOOK1.2_LIBRARIES LIBEBOOK1.2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindECal1.0.cmake b/cmake/modules/FindECal1.0.cmake
new file mode 100644
index 0000000..086258a
--- /dev/null
+++ b/cmake/modules/FindECal1.0.cmake
@@ -0,0 +1,102 @@
+# - Try to find libecal1.0 components
+# Find libecal 1.0 headers, libraries and the answer to all questions.
+#
+#  LIBECAL1.0_FOUND               True if libecal1.0 got found
+#  LIBECAL1.0_INCLUDE_DIRS         Location of libecal1.0 headers 
+#  LIBECAL1.0_LIBRARIES           List of libaries to use libecal1.0
+#  LIBECAL1.0_DEFINITIONS         Definitions to compile libecal1.0 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libecal-1.0.pc settings
+IF ( ECal1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( ECal1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( ECal1.0_FIND_REQUIRED )
+
+pkg_search_module( LIBECAL1.0 ${_pkgconfig_REQUIRED} libecal-1.0 )
+
+
+# Look for libecal1.0 include dir and libraries w/o pkg-config.
+IF ( NOT LIBECAL1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libecal1.0_include_DIR libecal/e-cal.h 
+			PATH_SUFFIXES evolution-data-server-1.12 evolution-data-server-1.10 evolution-data-server-1.8 evolution-data-server-1.6 evolution-data-server-1.4 evolution-data-server-1.0
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+	FIND_LIBRARY( _libecal1.0_link_DIR ecal-1.0
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+        IF ( _libecal1.0_include_DIR AND _libecal1.0_link_DIR )
+                SET ( _libecal1.0_FOUND TRUE )
+        ENDIF ( _libecal1.0_include_DIR AND _libecal1.0_link_DIR )
+
+
+        IF ( _libecal1.0_FOUND )
+                SET ( LIBECAL1.0_INCLUDE_DIRS ${_libecal1.0_include_DIR} )
+                SET ( LIBECAL1.0_LIBRARIES ${_libecal1.0_link_DIR} )
+        ENDIF ( _libecal1.0_FOUND )
+
+        # Handle dependencies
+	IF ( NOT LIBEDATASERVER1.0_FOUND )
+		FIND_PACKAGE ( EDataServer1.0 REQUIRED )
+                IF ( LIBEDATASERVER1.0_FOUND )
+                        SET ( LIBECAL1.0_INCLUDE_DIRS ${LIBECAL1.0_INCLUDE_DIRS} ${LIBEDATASERVER1.0_INCLUDE_DIRS} )
+                        SET ( LIBECAL1.0_LIBRARIES ${LIBECAL1.0_LIBRARIES} ${LIBEDATASERVER1.0_LIBRARIES} )
+                ENDIF ( LIBEDATASERVER1.0_FOUND )		
+	ENDIF ( NOT LIBEDATASERVER1.0_FOUND )
+	IF ( NOT LIBGNOME2_FOUND )
+		FIND_PACKAGE ( LibGnome2 REQUIRED )
+                IF ( LIBGNOME2_FOUND )
+                        SET ( LIBECAL1.0_INCLUDE_DIRS ${LIBECAL1.0_INCLUDE_DIRS} ${LIBGNOME2_INCLUDE_DIRS} )
+                        SET ( LIBECAL1.0_LIBRARIES ${LIBECAL1.0_LIBRARIES} ${LIBGNOME2_LIBRARIES} )
+                ENDIF ( LIBGNOME2_FOUND )		
+	ENDIF ( NOT LIBGNOME2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( LIBECAL1.0_INCLUDE_DIRS ${LIBECAL1.0_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( LIBECAL1.0_LIBRARIES ${LIBECAL1.0_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+
+	# Report results
+	IF ( LIBECAL1.0_LIBRARIES AND LIBECAL1.0_INCLUDE_DIRS AND _libecal1.0_FOUND )
+		SET( LIBECAL1.0_FOUND 1 )
+		IF ( NOT ECal1.0_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libecal-1.0: ${LIBECAL1.0_LIBRARIES}" )
+		ENDIF ( NOT ECal1.0_FIND_QUIETLY )
+	ELSE ( LIBECAL1.0_LIBRARIES AND LIBECAL1.0_INCLUDE_DIRS AND _libecal1.0_FOUND )	
+		IF ( ECal1.0_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libecal-1.0" )
+		ELSE ( ECal1.0_FIND_REQUIRED )
+			IF ( NOT ECal1.0_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libecal-1.0" )	
+			ENDIF ( NOT ECal1.0_FIND_QUIETLY )
+		ENDIF ( ECal1.0_FIND_REQUIRED )
+	ENDIF ( LIBECAL1.0_LIBRARIES AND LIBECAL1.0_INCLUDE_DIRS AND _libecal1.0_FOUND )	
+
+ENDIF ( NOT LIBECAL1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBECAL1.0_LIBRARIES LIBECAL1.0_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindECal1.2.cmake b/cmake/modules/FindECal1.2.cmake
new file mode 100644
index 0000000..7a22db4
--- /dev/null
+++ b/cmake/modules/FindECal1.2.cmake
@@ -0,0 +1,103 @@
+# - Try to find libecal1.2 components
+# Find libecal 1.2 headers, libraries and the answer to all questions.
+#
+#  LIBECAL1.2_FOUND               True if libecal1.2 got found
+#  LIBECAL1.2_INCLUDE_DIRS         Location of libecal1.2 headers 
+#  LIBECAL1.2_LIBRARIES           List of libaries to use libecal1.2
+#  LIBECAL1.2_DEFINITIONS         Definitions to compile libecal1.2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libecal-1.2.pc settings
+IF ( ECal1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( ECal1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( ECal1.2_FIND_REQUIRED )
+
+pkg_search_module( LIBECAL1.2 ${_pkgconfig_REQUIRED} libecal-1.2 )
+
+
+# Look for libecal1.2 include dir and libraries w/o pkg-config.
+IF ( NOT LIBECAL1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libecal1.2_include_DIR libecal/e-cal.h 
+			PATH_SUFFIXES evolution-data-server-1.12 evolution-data-server-1.10 evolution-data-server-1.8 evolution-data-server-1.6 evolution-data-server-1.4 evolution-data-server-1.2
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+	FIND_LIBRARY( _libecal1.2_link_DIR ecal-1.2
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+        IF ( _libecal1.2_include_DIR AND _libecal1.2_link_DIR )
+                SET ( _libecal1.2_FOUND TRUE )
+        ENDIF ( _libecal1.2_include_DIR AND _libecal1.2_link_DIR )
+
+
+        IF ( _libecal1.2_FOUND )
+                SET ( LIBECAL1.2_INCLUDE_DIRS ${_libecal1.2_include_DIR} )
+                SET ( LIBECAL1.2_LIBRARIES ${_libecal1.2_link_DIR} )
+        ENDIF ( _libecal1.2_FOUND )
+
+        # Handle dependencies
+	IF ( NOT LIBEDATASERVER1.2_FOUND )
+		FIND_PACKAGE ( EDataServer1.2 REQUIRED )
+                IF ( LIBEDATASERVER1.2_FOUND )
+                        SET ( LIBECAL1.2_INCLUDE_DIRS ${LIBECAL1.2_INCLUDE_DIRS} ${LIBEDATASERVER1.2_INCLUDE_DIRS} )
+                        SET ( LIBECAL1.2_LIBRARIES ${LIBECAL1.2_LIBRARIES} ${LIBEDATASERVER1.2_LIBRARIES} )
+                ENDIF ( LIBEDATASERVER1.2_FOUND )		
+	ENDIF ( NOT LIBEDATASERVER1.2_FOUND )
+	IF ( NOT LIBGNOME2_FOUND )
+		FIND_PACKAGE ( LibGnome2 REQUIRED )
+                IF ( LIBGNOME2_FOUND )
+                        SET ( LIBECAL1.2_INCLUDE_DIRS ${LIBECAL1.2_INCLUDE_DIRS} ${LIBGNOME2_INCLUDE_DIRS} )
+                        SET ( LIBECAL1.2_LIBRARIES ${LIBECAL1.2_LIBRARIES} ${LIBGNOME2_LIBRARIES} )
+                ENDIF ( LIBGNOME2_FOUND )		
+	ENDIF ( NOT LIBGNOME2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		SET ( BONOBO2_MIN_VERSION "2.4.2" )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( LIBECAL1.2_INCLUDE_DIRS ${LIBECAL1.2_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( LIBECAL1.2_LIBRARIES ${LIBECAL1.2_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+
+	# Report results
+	IF ( LIBECAL1.2_LIBRARIES AND LIBECAL1.2_INCLUDE_DIRS AND _libecal1.2_FOUND )
+		SET( LIBECAL1.2_FOUND 1 )
+		IF ( NOT ECal1.2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libecal-1.2: ${LIBECAL1.2_LIBRARIES}" )
+		ENDIF ( NOT ECal1.2_FIND_QUIETLY )
+	ELSE ( LIBECAL1.2_LIBRARIES AND LIBECAL1.2_INCLUDE_DIRS AND _libecal1.2_FOUND )	
+		IF ( ECal1.2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libecal-1.2" )
+		ELSE ( ECal1.2_FIND_REQUIRED )
+			IF ( NOT ECal1.2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libecal-1.2" )	
+			ENDIF ( NOT ECal1.2_FIND_QUIETLY )
+		ENDIF ( ECal1.2_FIND_REQUIRED )
+	ENDIF ( LIBECAL1.2_LIBRARIES AND LIBECAL1.2_INCLUDE_DIRS AND _libecal1.2_FOUND )	
+
+ENDIF ( NOT LIBECAL1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBECAL1.2_LIBRARIES LIBECAL1.2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindEDataBook1.0.cmake b/cmake/modules/FindEDataBook1.0.cmake
new file mode 100644
index 0000000..069eddc
--- /dev/null
+++ b/cmake/modules/FindEDataBook1.0.cmake
@@ -0,0 +1,110 @@
+# - Try to find libedatabook1.0 components
+# Find libedatabook 1.0 headers, libraries and the answer to all questions.
+#
+#  LIBEDATABOOK1.0_FOUND               True if libedatabook1.0 got found
+#  LIBEDATABOOK1.0_INCLUDE_DIRS         Location of libedatabook1.0 headers 
+#  LIBEDATABOOK1.0_LIBRARIES           List of libaries to use libedatabook1.0
+#  LIBEDATABOOK1.0_DEFINITIONS         Definitions to compile libedatabook1.0 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libedata-book-1.0.pc settings
+IF ( EDataBook1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( EDataBook1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( EDataBook1.0_FIND_REQUIRED )
+
+pkg_search_module( LIBEDATABOOK1.0 ${_pkgconfig_REQUIRED} libedata-book-1.0 )
+
+
+# Look for libedatabook1.0 include dir and libraries w/o pkg-config.
+IF ( NOT LIBEDATABOOK1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libedatabook1.0_include_DIR libedata-book/e-data-book.h 
+			PATH_SUFFIXES evolution-data-server-1.12 evolution-data-server-1.10 evolution-data-server-1.8 evolution-data-server-1.6 evolution-data-server-1.4 evolution-data-server-1.0
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+	FIND_LIBRARY( _libedatabook1.0_link_DIR edata-book-1.0
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+        IF ( _libedatabook1.0_include_DIR AND _libedatabook1.0_link_DIR )
+                SET ( _libedatabook1.0_FOUND TRUE )
+        ENDIF ( _libedatabook1.0_include_DIR AND _libedatabook1.0_link_DIR )
+
+
+        IF ( _libedatabook1.0_FOUND )
+                SET ( LIBEDATABOOK1.0_INCLUDE_DIRS ${_libedatabook1.0_include_DIR} )
+                SET ( LIBEDATABOOK1.0_LIBRARIES ${_libedatabook1.0_link_DIR} )
+        ENDIF ( _libedatabook1.0_FOUND )
+
+        # Handle dependencies
+	IF ( NOT LIBEBOOK1.0_FOUND )
+		FIND_PACKAGE ( EBook1.0 REQUIRED )
+                IF ( LIBEBOOK1.0_FOUND )
+                        SET ( LIBEDATABOOK1.0_INCLUDE_DIRS ${LIBEDATABOOK1.0_INCLUDE_DIRS} ${LIBEBOOK1.0_INCLUDE_DIRS} )
+                        SET ( LIBEDATABOOK1.0_LIBRARIES ${LIBEDATABOOK1.0_LIBRARIES} ${LIBEBOOK1.0_LIBRARIES} )
+                ENDIF ( LIBEBOOK1.0_FOUND )		
+	ENDIF ( NOT LIBEBOOK1.0_FOUND )
+	IF ( NOT LIBEDATASERVER1.0_FOUND )
+		FIND_PACKAGE ( EDataServer1.0 REQUIRED )
+                IF ( LIBEDATASERVER1.0_FOUND )
+                        SET ( LIBEDATABOOK1.0_INCLUDE_DIRS ${LIBEDATABOOK1.0_INCLUDE_DIRS} ${LIBEDATASERVER1.0_INCLUDE_DIRS} )
+                        SET ( LIBEDATABOOK1.0_LIBRARIES ${LIBEDATABOOK1.0_LIBRARIES} ${LIBEDATASERVER1.0_LIBRARIES} )
+                ENDIF ( LIBEDATASERVER1.0_FOUND )		
+	ENDIF ( NOT LIBEDATASERVER1.0_FOUND )
+	IF ( NOT LIBGNOME2_FOUND )
+		FIND_PACKAGE ( LibGnome2 REQUIRED )
+                IF ( LIBGNOME2_FOUND )
+                        SET ( LIBEDATABOOK1.0_INCLUDE_DIRS ${LIBEDATABOOK1.0_INCLUDE_DIRS} ${LIBGNOME2_INCLUDE_DIRS} )
+                        SET ( LIBEDATABOOK1.0_LIBRARIES ${LIBEDATABOOK1.0_LIBRARIES} ${LIBGNOME2_LIBRARIES} )
+                ENDIF ( LIBGNOME2_FOUND )		
+	ENDIF ( NOT LIBGNOME2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		SET ( BONOBO2_MIN_VERSION "2.4.2" )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( LIBEDATABOOK1.0_INCLUDE_DIRS ${LIBEDATABOOK1.0_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( LIBEDATABOOK1.0_LIBRARIES ${LIBEDATABOOK1.0_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+
+	# Report results
+	IF ( LIBEDATABOOK1.0_LIBRARIES AND LIBEDATABOOK1.0_INCLUDE_DIRS AND _libedatabook1.0_FOUND )
+		SET( LIBEDATABOOK1.0_FOUND 1 )
+		IF ( NOT EDataBook1.0_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libedatabook-1.0: ${LIBEDATABOOK1.0_LIBRARIES}" )
+		ENDIF ( NOT EDataBook1.0_FIND_QUIETLY )
+	ELSE ( LIBEDATABOOK1.0_LIBRARIES AND LIBEDATABOOK1.0_INCLUDE_DIRS AND _libedatabook1.0_FOUND )	
+		IF ( EDataBook1.0_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libedatabook-1.0" )
+		ELSE ( EDataBook1.0_FIND_REQUIRED )
+			IF ( NOT EDataBook1.0_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libedatabook-1.0" )	
+			ENDIF ( NOT EDataBook1.0_FIND_QUIETLY )
+		ENDIF ( EDataBook1.0_FIND_REQUIRED )
+	ENDIF ( LIBEDATABOOK1.0_LIBRARIES AND LIBEDATABOOK1.0_INCLUDE_DIRS AND _libedatabook1.0_FOUND )	
+
+ENDIF ( NOT LIBEDATABOOK1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBEDATABOOK1.0_LIBRARIES LIBEDATABOOK1.0_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindEDataBook1.2.cmake b/cmake/modules/FindEDataBook1.2.cmake
new file mode 100644
index 0000000..22381f9
--- /dev/null
+++ b/cmake/modules/FindEDataBook1.2.cmake
@@ -0,0 +1,110 @@
+# - Try to find libedatabook1.2 components
+# Find libedatabook 1.2 headers, libraries and the answer to all questions.
+#
+#  LIBEDATABOOK1.2_FOUND               True if libedatabook1.2 got found
+#  LIBEDATABOOK1.2_INCLUDE_DIRS         Location of libedatabook1.2 headers 
+#  LIBEDATABOOK1.2_LIBRARIES           List of libaries to use libedatabook1.2
+#  LIBEDATABOOK1.2_DEFINITIONS         Definitions to compile libedatabook1.2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libedata-book-1.2.pc settings
+IF ( EDataBook1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( EDataBook1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( EDataBook1.2_FIND_REQUIRED )
+
+pkg_search_module( LIBEDATABOOK1.2 ${_pkgconfig_REQUIRED} libedata-book-1.2 )
+
+
+# Look for libedatabook1.2 include dir and libraries w/o pkg-config.
+IF ( NOT LIBEDATABOOK1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libedatabook1.2_include_DIR libedata-book/e-data-book.h 
+			PATH_SUFFIXES evolution-data-server-1.12 evolution-data-server-1.10 evolution-data-server-1.8 evolution-data-server-1.6 evolution-data-server-1.4 evolution-data-server-1.2
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+	FIND_LIBRARY( _libedatabook1.2_link_DIR edata-book-1.2
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+        IF ( _libedatabook1.2_include_DIR AND _libedatabook1.2_link_DIR )
+                SET ( _libedatabook1.2_FOUND TRUE )
+        ENDIF ( _libedatabook1.2_include_DIR AND _libedatabook1.2_link_DIR )
+
+
+        IF ( _libedatabook1.2_FOUND )
+                SET ( LIBEDATABOOK1.2_INCLUDE_DIRS ${_libedatabook1.2_include_DIR} )
+                SET ( LIBEDATABOOK1.2_LIBRARIES ${_libedatabook1.2_link_DIR} )
+        ENDIF ( _libedatabook1.2_FOUND )
+
+        # Handle dependencies
+	IF ( NOT LIBEBOOK1.2_FOUND )
+		FIND_PACKAGE ( EBook1.2 REQUIRED )
+                IF ( LIBEBOOK1.2_FOUND )
+                        SET ( LIBEDATABOOK1.2_INCLUDE_DIRS ${LIBEDATABOOK1.2_INCLUDE_DIRS} ${LIBEBOOK1.2_INCLUDE_DIRS} )
+                        SET ( LIBEDATABOOK1.2_LIBRARIES ${LIBEDATABOOK1.2_LIBRARIES} ${LIBEBOOK1.2_LIBRARIES} )
+                ENDIF ( LIBEBOOK1.2_FOUND )		
+	ENDIF ( NOT LIBEBOOK1.2_FOUND )
+	IF ( NOT LIBEDATASERVER1.2_FOUND )
+		FIND_PACKAGE ( EDataServer1.2 REQUIRED )
+                IF ( LIBEDATASERVER1.2_FOUND )
+                        SET ( LIBEDATABOOK1.2_INCLUDE_DIRS ${LIBEDATABOOK1.2_INCLUDE_DIRS} ${LIBEDATASERVER1.2_INCLUDE_DIRS} )
+                        SET ( LIBEDATABOOK1.2_LIBRARIES ${LIBEDATABOOK1.2_LIBRARIES} ${LIBEDATASERVER1.2_LIBRARIES} )
+                ENDIF ( LIBEDATASERVER1.2_FOUND )		
+	ENDIF ( NOT LIBEDATASERVER1.2_FOUND )
+	IF ( NOT LIBGNOME2_FOUND )
+		FIND_PACKAGE ( LibGnome2 REQUIRED )
+                IF ( LIBGNOME2_FOUND )
+                        SET ( LIBEDATABOOK1.2_INCLUDE_DIRS ${LIBEDATABOOK1.2_INCLUDE_DIRS} ${LIBGNOME2_INCLUDE_DIRS} )
+                        SET ( LIBEDATABOOK1.2_LIBRARIES ${LIBEDATABOOK1.2_LIBRARIES} ${LIBGNOME2_LIBRARIES} )
+                ENDIF ( LIBGNOME2_FOUND )		
+	ENDIF ( NOT LIBGNOME2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		SET ( BONOBO2_MIN_VERSION "2.4.2" )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( LIBEDATABOOK1.2_INCLUDE_DIRS ${LIBEDATABOOK1.2_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( LIBEDATABOOK1.2_LIBRARIES ${LIBEDATABOOK1.2_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+
+	# Report results
+	IF ( LIBEDATABOOK1.2_LIBRARIES AND LIBEDATABOOK1.2_INCLUDE_DIRS AND _libedatabook1.2_FOUND )
+		SET( LIBEDATABOOK1.2_FOUND 1 )
+		IF ( NOT EDataBook1.2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libedatabook-1.2: ${LIBEDATABOOK1.2_LIBRARIES}" )
+		ENDIF ( NOT EDataBook1.2_FIND_QUIETLY )
+	ELSE ( LIBEDATABOOK1.2_LIBRARIES AND LIBEDATABOOK1.2_INCLUDE_DIRS AND _libedatabook1.2_FOUND )	
+		IF ( EDataBook1.2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libedatabook-1.2" )
+		ELSE ( EDataBook1.2_FIND_REQUIRED )
+			IF ( NOT EDataBook1.2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libedatabook-1.2" )	
+			ENDIF ( NOT EDataBook1.2_FIND_QUIETLY )
+		ENDIF ( EDataBook1.2_FIND_REQUIRED )
+	ENDIF ( LIBEDATABOOK1.2_LIBRARIES AND LIBEDATABOOK1.2_INCLUDE_DIRS AND _libedatabook1.2_FOUND )	
+
+ENDIF ( NOT LIBEDATABOOK1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBEDATABOOK1.2_LIBRARIES LIBEDATABOOK1.2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindEDataCal1.0.cmake b/cmake/modules/FindEDataCal1.0.cmake
new file mode 100644
index 0000000..82044d2
--- /dev/null
+++ b/cmake/modules/FindEDataCal1.0.cmake
@@ -0,0 +1,117 @@
+# - Try to find libedatacal1.0 components
+# Find libedatacal 1.0 headers, libraries and the answer to all questions.
+#
+#  LIBEDATACAL1.0_FOUND               True if libedatacal1.0 got found
+#  LIBEDATACAL1.0_INCLUDE_DIRS         Location of libedatacal1.0 headers 
+#  LIBEDATACAL1.0_LIBRARIES           List of libaries to use libedatacal1.0
+#  LIBEDATACAL1.0_DEFINITIONS         Definitions to compile libedatacal1.0 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libedata-cal-1.0.pc settings
+IF ( EDataCal1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( EDataCal1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( EDataCal1.0_FIND_REQUIRED )
+
+pkg_search_module( LIBEDATACAL1.0 ${_pkgconfig_REQUIRED} libedata-cal-1.0 )
+
+
+# Look for libedatacal1.0 include dir and libraries w/o pkg-config.
+IF ( NOT LIBEDATACAL1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libedatacal1.0_include_DIR libedata-cal/e-data-cal.h 
+			PATH_SUFFIXES evolution-data-server-1.12 evolution-data-server-1.10 evolution-data-server-1.8 evolution-data-server-1.6 evolution-data-server-1.4 evolution-data-server-1.0
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+	FIND_LIBRARY( _libedatacal1.0_link_DIR edata-cal-1.0
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+        IF ( _libedatacal1.0_include_DIR AND _libedatacal1.0_link_DIR )
+                SET ( _libedatacal1.0_FOUND TRUE )
+        ENDIF ( _libedatacal1.0_include_DIR AND _libedatacal1.0_link_DIR )
+
+
+        IF ( _libedatacal1.0_FOUND )
+                SET ( LIBEDATACAL1.0_INCLUDE_DIRS ${_libedatacal1.0_include_DIR} )
+                SET ( LIBEDATACAL1.0_LIBRARIES ${_libedatacal1.0_link_DIR} )
+        ENDIF ( _libedatacal1.0_FOUND )
+
+        # Handle dependencies
+	IF ( NOT LIBECAL1.0_FOUND )
+		FIND_PACKAGE ( ECal1.0 REQUIRED )
+                IF ( LIBECAL1.0_FOUND )
+                        SET ( LIBEDATACAL1.0_INCLUDE_DIRS ${LIBEDATACAL1.0_INCLUDE_DIRS} ${LIBECAL1.0_INCLUDE_DIRS} )
+                        SET ( LIBEDATACAL1.0_LIBRARIES ${LIBEDATACAL1.0_LIBRARIES} ${LIBECAL1.0_LIBRARIES} )
+                ENDIF ( LIBECAL1.0_FOUND )		
+	ENDIF ( NOT LIBECAL1.0_FOUND )
+	IF ( NOT GNOMEVFS2_FOUND )
+		FIND_PACKAGE ( GnomeVfs2 REQUIRED )
+                IF ( GNOMEVFS2_FOUND )
+                        SET ( LIBEDATACAL1.0_INCLUDE_DIRS ${LIBEDATACAL1.0_INCLUDE_DIRS} ${GNOMEVFS2_INCLUDE_DIRS} )
+                        SET ( LIBEDATACAL1.0_LIBRARIES ${LIBEDATACAL1.0_LIBRARIES} ${GNOMEVFS2_LIBRARIES} )
+                ENDIF ( GNOMEVFS2_FOUND )		
+	ENDIF ( NOT GNOMEVFS2_FOUND )
+	IF ( NOT LIBEDATASERVER1.0_FOUND )
+		FIND_PACKAGE ( EDataServer1.0 REQUIRED )
+                IF ( LIBEDATASERVER1.0_FOUND )
+                        SET ( LIBEDATACAL1.0_INCLUDE_DIRS ${LIBEDATACAL1.0_INCLUDE_DIRS} ${LIBEDATASERVER1.0_INCLUDE_DIRS} )
+                        SET ( LIBEDATACAL1.0_LIBRARIES ${LIBEDATACAL1.0_LIBRARIES} ${LIBEDATASERVER1.0_LIBRARIES} )
+                ENDIF ( LIBEDATASERVER1.0_FOUND )		
+	ENDIF ( NOT LIBEDATASERVER1.0_FOUND )
+	IF ( NOT LIBGNOME2_FOUND )
+		FIND_PACKAGE ( LibGnome2 REQUIRED )
+                IF ( LIBGNOME2_FOUND )
+                        SET ( LIBEDATACAL1.0_INCLUDE_DIRS ${LIBEDATACAL1.0_INCLUDE_DIRS} ${LIBGNOME2_INCLUDE_DIRS} )
+                        SET ( LIBEDATACAL1.0_LIBRARIES ${LIBEDATACAL1.0_LIBRARIES} ${LIBGNOME2_LIBRARIES} )
+                ENDIF ( LIBGNOME2_FOUND )		
+	ENDIF ( NOT LIBGNOME2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		SET ( BONOBO2_MIN_VERSION "2.4.2" )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( LIBEDATACAL1.0_INCLUDE_DIRS ${LIBEDATACAL1.0_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( LIBEDATACAL1.0_LIBRARIES ${LIBEDATACAL1.0_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+
+	# Report results
+	IF ( LIBEDATACAL1.0_LIBRARIES AND LIBEDATACAL1.0_INCLUDE_DIRS AND _libedatacal1.0_FOUND )
+		SET( LIBEDATACAL1.0_FOUND 1 )
+		IF ( NOT EDataCal1.0_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libedatacal-1.0: ${LIBEDATACAL1.0_LIBRARIES}" )
+		ENDIF ( NOT EDataCal1.0_FIND_QUIETLY )
+	ELSE ( LIBEDATACAL1.0_LIBRARIES AND LIBEDATACAL1.0_INCLUDE_DIRS AND _libedatacal1.0_FOUND )	
+		IF ( EDataCal1.0_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libedatacal-1.0" )
+		ELSE ( EDataCal1.0_FIND_REQUIRED )
+			IF ( NOT EDataCal1.0_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libedatacal-1.0" )	
+			ENDIF ( NOT EDataCal1.0_FIND_QUIETLY )
+		ENDIF ( EDataCal1.0_FIND_REQUIRED )
+	ENDIF ( LIBEDATACAL1.0_LIBRARIES AND LIBEDATACAL1.0_INCLUDE_DIRS AND _libedatacal1.0_FOUND )	
+
+ENDIF ( NOT LIBEDATACAL1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBEDATACAL1.0_LIBRARIES LIBEDATACAL1.0_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindEDataCal1.2.cmake b/cmake/modules/FindEDataCal1.2.cmake
new file mode 100644
index 0000000..5f209b8
--- /dev/null
+++ b/cmake/modules/FindEDataCal1.2.cmake
@@ -0,0 +1,117 @@
+# - Try to find libedatacal1.2 components
+# Find libedatacal 1.2 headers, libraries and the answer to all questions.
+#
+#  LIBEDATACAL1.2_FOUND               True if libedatacal1.2 got found
+#  LIBEDATACAL1.2_INCLUDE_DIRS         Location of libedatacal1.2 headers 
+#  LIBEDATACAL1.2_LIBRARIES           List of libaries to use libedatacal1.2
+#  LIBEDATACAL1.2_DEFINITIONS         Definitions to compile libedatacal1.2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libedata-cal-1.2.pc settings
+IF ( EDataCal1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( EDataCal1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( EDataCal1.2_FIND_REQUIRED )
+
+pkg_search_module( LIBEDATACAL1.2 ${_pkgconfig_REQUIRED} libedata-cal-1.2 )
+
+
+# Look for libedatacal1.2 include dir and libraries w/o pkg-config.
+IF ( NOT LIBEDATACAL1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libedatacal1.2_include_DIR libedata-cal/e-data-cal.h 
+			PATH_SUFFIXES evolution-data-server-1.12 evolution-data-server-1.10 evolution-data-server-1.8 evolution-data-server-1.6 evolution-data-server-1.4 evolution-data-server-1.2
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+	FIND_LIBRARY( _libedatacal1.2_link_DIR edata-cal-1.2
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+        IF ( _libedatacal1.2_include_DIR AND _libedatacal1.2_link_DIR )
+                SET ( _libedatacal1.2_FOUND TRUE )
+        ENDIF ( _libedatacal1.2_include_DIR AND _libedatacal1.2_link_DIR )
+
+
+        IF ( _libedatacal1.2_FOUND )
+                SET ( LIBEDATACAL1.2_INCLUDE_DIRS ${_libedatacal1.2_include_DIR} )
+                SET ( LIBEDATACAL1.2_LIBRARIES ${_libedatacal1.2_link_DIR} )
+        ENDIF ( _libedatacal1.2_FOUND )
+
+        # Handle dependencies
+	IF ( NOT LIBECAL1.2_FOUND )
+		FIND_PACKAGE ( ECal1.2 REQUIRED )
+                IF ( LIBECAL1.2_FOUND )
+                        SET ( LIBEDATACAL1.2_INCLUDE_DIRS ${LIBEDATACAL1.2_INCLUDE_DIRS} ${LIBECAL1.2_INCLUDE_DIRS} )
+                        SET ( LIBEDATACAL1.2_LIBRARIES ${LIBEDATACAL1.2_LIBRARIES} ${LIBECAL1.2_LIBRARIES} )
+                ENDIF ( LIBECAL1.2_FOUND )		
+	ENDIF ( NOT LIBECAL1.2_FOUND )
+	IF ( NOT GNOMEVFS2_FOUND )
+		FIND_PACKAGE ( GnomeVfs2 REQUIRED )
+                IF ( GNOMEVFS2_FOUND )
+                        SET ( LIBEDATACAL1.2_INCLUDE_DIRS ${LIBEDATACAL1.2_INCLUDE_DIRS} ${GNOMEVFS2_INCLUDE_DIRS} )
+                        SET ( LIBEDATACAL1.2_LIBRARIES ${LIBEDATACAL1.2_LIBRARIES} ${GNOMEVFS2_LIBRARIES} )
+                ENDIF ( GNOMEVFS2_FOUND )		
+	ENDIF ( NOT GNOMEVFS2_FOUND )
+	IF ( NOT LIBEDATASERVER1.2_FOUND )
+		FIND_PACKAGE ( EDataServer1.2 REQUIRED )
+                IF ( LIBEDATASERVER1.2_FOUND )
+                        SET ( LIBEDATACAL1.2_INCLUDE_DIRS ${LIBEDATACAL1.2_INCLUDE_DIRS} ${LIBEDATASERVER1.2_INCLUDE_DIRS} )
+                        SET ( LIBEDATACAL1.2_LIBRARIES ${LIBEDATACAL1.2_LIBRARIES} ${LIBEDATASERVER1.2_LIBRARIES} )
+                ENDIF ( LIBEDATASERVER1.2_FOUND )		
+	ENDIF ( NOT LIBEDATASERVER1.2_FOUND )
+	IF ( NOT LIBGNOME2_FOUND )
+		FIND_PACKAGE ( LibGnome2 REQUIRED )
+                IF ( LIBGNOME2_FOUND )
+                        SET ( LIBEDATACAL1.2_INCLUDE_DIRS ${LIBEDATACAL1.2_INCLUDE_DIRS} ${LIBGNOME2_INCLUDE_DIRS} )
+                        SET ( LIBEDATACAL1.2_LIBRARIES ${LIBEDATACAL1.2_LIBRARIES} ${LIBGNOME2_LIBRARIES} )
+                ENDIF ( LIBGNOME2_FOUND )		
+	ENDIF ( NOT LIBGNOME2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		SET ( BONOBO2_MIN_VERSION "2.4.2" )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( LIBEDATACAL1.2_INCLUDE_DIRS ${LIBEDATACAL1.2_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( LIBEDATACAL1.2_LIBRARIES ${LIBEDATACAL1.2_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+
+	# Report results
+	IF ( LIBEDATACAL1.2_LIBRARIES AND LIBEDATACAL1.2_INCLUDE_DIRS AND _libedatacal1.2_FOUND )
+		SET( LIBEDATACAL1.2_FOUND 1 )
+		IF ( NOT EDataCal1.2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libedatacal-1.2: ${LIBEDATACAL1.2_LIBRARIES}" )
+		ENDIF ( NOT EDataCal1.2_FIND_QUIETLY )
+	ELSE ( LIBEDATACAL1.2_LIBRARIES AND LIBEDATACAL1.2_INCLUDE_DIRS AND _libedatacal1.2_FOUND )	
+		IF ( EDataCal1.2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libedatacal-1.2" )
+		ELSE ( EDataCal1.2_FIND_REQUIRED )
+			IF ( NOT EDataCal1.2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libedatacal-1.2" )	
+			ENDIF ( NOT EDataCal1.2_FIND_QUIETLY )
+		ENDIF ( EDataCal1.2_FIND_REQUIRED )
+	ENDIF ( LIBEDATACAL1.2_LIBRARIES AND LIBEDATACAL1.2_INCLUDE_DIRS AND _libedatacal1.2_FOUND )	
+
+ENDIF ( NOT LIBEDATACAL1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBEDATACAL1.2_LIBRARIES LIBEDATACAL1.2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindEDataServer1.0.cmake b/cmake/modules/FindEDataServer1.0.cmake
new file mode 100644
index 0000000..9b64083
--- /dev/null
+++ b/cmake/modules/FindEDataServer1.0.cmake
@@ -0,0 +1,119 @@
+# - Try to find libedataserver1.0 components
+# Find libedataserver 1.0 headers, libraries and the answer to all questions.
+#
+#  LIBEDATASERVER1.0_FOUND               True if libedataserver1.0 got found
+#  LIBEDATASERVER1.0_INCLUDE_DIRS         Location of libedataserver1.0 headers 
+#  LIBEDATASERVER1.0_LIBRARIES           List of libaries to use libedataserver1.0
+#  LIBEDATASERVER1.0_DEFINITIONS         Definitions to compile libedataserver1.0 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libedataserver-1.0.pc settings
+IF ( EDataServer1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( EDataServer1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( EDataServer1.0_FIND_REQUIRED )
+
+pkg_search_module( LIBEDATASERVER1.0 ${_pkgconfig_REQUIRED} libedataserver-1.0 )
+
+
+# Look for libedataserver1.0 include dir and libraries w/o pkg-config.
+IF ( NOT LIBEDATASERVER1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libedataserver1.0_include_DIR libedataserver/e-account.h 
+			PATH_SUFFIXES evolution-data-server-1.12 evolution-data-server-1.10 evolution-data-server-1.8 evolution-data-server-1.6 evolution-data-server-1.4 evolution-data-server-1.0
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+	FIND_LIBRARY( _libedataserver1.0_link_DIR edataserver-1.0
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+        IF ( _libedataserver1.0_include_DIR AND _libedataserver1.0_link_DIR )
+                SET ( _libedataserver1.0_FOUND TRUE )
+        ENDIF ( _libedataserver1.0_include_DIR AND _libedataserver1.0_link_DIR )
+
+
+        IF ( _libedataserver1.0_FOUND )
+                SET ( LIBEDATASERVER1.0_INCLUDE_DIRS ${_libedataserver1.0_include_DIR} )
+                SET ( LIBEDATASERVER1.0_LIBRARIES ${_libedataserver1.0_link_DIR} )
+        ENDIF ( _libedataserver1.0_FOUND )
+
+
+        # Handle dependencies
+	IF ( NOT GCONF2_FOUND )
+		FIND_PACKAGE ( GConf2 REQUIRED )
+                IF ( GCONF2_FOUND )
+                        SET ( LIBEDATASERVER1.0_INCLUDE_DIRS ${LIBEDATASERVER1.0_INCLUDE_DIRS} ${GCONF2_INCLUDE_DIRS} )
+                        SET ( LIBEDATASERVER1.0_LIBRARIES ${LIBEDATASERVER1.0_LIBRARIES} ${GCONF2_LIBRARIES} )
+                ENDIF ( GCONF2_FOUND )		
+	ENDIF ( NOT GCONF2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		SET ( BONOBO2_MIN_VERSION "2.4.2" )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( LIBEDATASERVER1.0_INCLUDE_DIRS ${LIBEDATASERVER1.0_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( LIBEDATASERVER1.0_LIBRARIES ${LIBEDATASERVER1.0_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+	IF ( NOT ORBIT2_FOUND )
+		SET ( ORBIT2_MIN_VERSION "2.9.8" )
+		FIND_PACKAGE ( ORBit2 REQUIRED )
+                IF ( ORBIT2_FOUND )
+                        SET ( LIBEDATASERVER1.0_INCLUDE_DIRS ${LIBEDATASERVER1.0_INCLUDE_DIRS} ${ORBIT2_INCLUDE_DIRS} )
+                        SET ( LIBEDATASERVER1.0_LIBRARIES ${LIBEDATASERVER1.0_LIBRARIES} ${ORBIT2_LIBRARIES} )
+                ENDIF ( ORBIT2_FOUND )		
+	ENDIF ( NOT ORBIT2_FOUND )
+	IF ( NOT LIBXML2_FOUND )
+		FIND_PACKAGE ( LibXml2 REQUIRED )
+                IF ( LIBXML2_FOUND )
+                        SET ( LIBEDATASERVER1.0_INCLUDE_DIRS ${LIBEDATASERVER1.0_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIRS} )
+                        SET ( LIBEDATASERVER1.0_LIBRARIES ${LIBEDATASERVER1.0_LIBRARIES} ${LIBXML2_LIBRARY} )
+                ENDIF ( LIBXML2_FOUND )		
+	ENDIF ( NOT LIBXML2_FOUND )
+	IF ( NOT GLIB2_FOUND )
+		FIND_PACKAGE ( GLIB2 REQUIRED )
+                IF ( GLIB2_FOUND )
+                        SET ( LIBEDATASERVER1.0_INCLUDE_DIRS ${LIBEDATASERVER1.0_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} ${GLIBCONFIG_INCLUDE_DIR} )
+                        SET ( LIBEDATASERVER1.0_LIBRARIES ${LIBEDATASERVER1.0_LIBRARIES} ${GLIB2_LIBRARIES} )
+                ENDIF ( GLIB2_FOUND )		
+	ENDIF ( NOT GLIB2_FOUND )
+
+	# Report results
+	IF ( LIBEDATASERVER1.0_LIBRARIES AND LIBEDATASERVER1.0_INCLUDE_DIRS AND _libedataserver1.0_FOUND )
+		SET( LIBEDATASERVER1.0_FOUND 1 )
+		IF ( NOT LibEDataServer1.0_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libedataserver-1.0: ${LIBEDATASERVER1.0_LIBRARIES}" )
+		ENDIF ( NOT LibEDataServer1.0_FIND_QUIETLY )
+	ELSE ( LIBEDATASERVER1.0_LIBRARIES AND LIBEDATASERVER1.0_INCLUDE_DIRS AND _libedataserver1.0_FOUND )	
+		IF ( LibEDataServer1.0_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libedataserver-1.0" )
+		ELSE ( LibEDataServer1.0_FIND_REQUIRED )
+			IF ( NOT LibEDataServer1.0_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libedataserver-1.0" )	
+			ENDIF ( NOT LibEDataServer1.0_FIND_QUIETLY )
+		ENDIF ( LibEDataServer1.0_FIND_REQUIRED )
+	ENDIF ( LIBEDATASERVER1.0_LIBRARIES AND LIBEDATASERVER1.0_INCLUDE_DIRS AND _libedataserver1.0_FOUND )	
+
+ENDIF ( NOT LIBEDATASERVER1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBEDATASERVER1.0_LIBRARIES LIBEDATASERVER1.0_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindEDataServer1.2.cmake b/cmake/modules/FindEDataServer1.2.cmake
new file mode 100644
index 0000000..a5a4140
--- /dev/null
+++ b/cmake/modules/FindEDataServer1.2.cmake
@@ -0,0 +1,119 @@
+# - Try to find libedataserver1.2 components
+# Find libedataserver 1.2 headers, libraries and the answer to all questions.
+#
+#  LIBEDATASERVER1.2_FOUND               True if libedataserver1.2 got found
+#  LIBEDATASERVER1.2_INCLUDE_DIRS         Location of libedataserver1.2 headers 
+#  LIBEDATASERVER1.2_LIBRARIES           List of libaries to use libedataserver1.2
+#  LIBEDATASERVER1.2_DEFINITIONS         Definitions to compile libedataserver1.2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libedataserver-1.2.pc settings
+IF ( EDataServer1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( EDataServer1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( EDataServer1.2_FIND_REQUIRED )
+
+pkg_search_module( LIBEDATASERVER1.2 ${_pkgconfig_REQUIRED} libedataserver-1.2 )
+
+
+# Look for libedataserver1.2 include dir and libraries w/o pkg-config.
+IF ( NOT LIBEDATASERVER1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libedataserver1.2_include_DIR libedataserver/e-account.h 
+			PATH_SUFFIXES evolution-data-server-1.12 evolution-data-server-1.10 evolution-data-server-1.8 evolution-data-server-1.6 evolution-data-server-1.4 evolution-data-server-1.2
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+	FIND_LIBRARY( _libedataserver1.2_link_DIR edataserver-1.2
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+        IF ( _libedataserver1.2_include_DIR AND _libedataserver1.2_link_DIR )
+                SET ( _libedataserver1.2_FOUND TRUE )
+        ENDIF ( _libedataserver1.2_include_DIR AND _libedataserver1.2_link_DIR )
+
+
+        IF ( _libedataserver1.2_FOUND )
+                SET ( LIBEDATASERVER1.2_INCLUDE_DIRS ${_libedataserver1.2_include_DIR} )
+                SET ( LIBEDATASERVER1.2_LIBRARIES ${_libedataserver1.2_link_DIR} )
+        ENDIF ( _libedataserver1.2_FOUND )
+
+
+        # Handle dependencies
+	IF ( NOT GCONF2_FOUND )
+		FIND_PACKAGE ( GConf2 REQUIRED )
+                IF ( GCONF2_FOUND )
+                        SET ( LIBEDATASERVER1.2_INCLUDE_DIRS ${LIBEDATASERVER1.2_INCLUDE_DIRS} ${GCONF2_INCLUDE_DIRS} )
+                        SET ( LIBEDATASERVER1.2_LIBRARIES ${LIBEDATASERVER1.2_LIBRARIES} ${GCONF2_LIBRARIES} )
+                ENDIF ( GCONF2_FOUND )		
+	ENDIF ( NOT GCONF2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		SET ( BONOBO2_MIN_VERSION "2.4.2" )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( LIBEDATASERVER1.2_INCLUDE_DIRS ${LIBEDATASERVER1.2_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( LIBEDATASERVER1.2_LIBRARIES ${LIBEDATASERVER1.2_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+	IF ( NOT ORBIT2_FOUND )
+		SET ( ORBIT2_MIN_VERSION "2.9.8" )
+		FIND_PACKAGE ( ORBit2 REQUIRED )
+                IF ( ORBIT2_FOUND )
+                        SET ( LIBEDATASERVER1.2_INCLUDE_DIRS ${LIBEDATASERVER1.2_INCLUDE_DIRS} ${ORBIT2_INCLUDE_DIRS} )
+                        SET ( LIBEDATASERVER1.2_LIBRARIES ${LIBEDATASERVER1.2_LIBRARIES} ${ORBIT2_LIBRARIES} )
+                ENDIF ( ORBIT2_FOUND )		
+	ENDIF ( NOT ORBIT2_FOUND )
+	IF ( NOT LIBXML2_FOUND )
+		FIND_PACKAGE ( LibXml2 REQUIRED )
+                IF ( LIBXML2_FOUND )
+                        SET ( LIBEDATASERVER1.2_INCLUDE_DIRS ${LIBEDATASERVER1.2_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIRS} )
+                        SET ( LIBEDATASERVER1.2_LIBRARIES ${LIBEDATASERVER1.2_LIBRARIES} ${LIBXML2_LIBRARIES} )
+                ENDIF ( LIBXML2_FOUND )		
+	ENDIF ( NOT LIBXML2_FOUND )
+	IF ( NOT GLIB2_FOUND )
+		FIND_PACKAGE ( GLIB2 REQUIRED )
+                IF ( GLIB2_FOUND )
+                        SET ( LIBEDATASERVER1.2_INCLUDE_DIRS ${LIBEDATASERVER1.2_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} ${GLIBCONFIG_INCLUDE_DIR} )
+                        SET ( LIBEDATASERVER1.2_LIBRARIES ${LIBEDATASERVER1.2_LIBRARIES} ${GLIB2_LIBRARIES} )
+                ENDIF ( GLIB2_FOUND )		
+	ENDIF ( NOT GLIB2_FOUND )
+
+	# Report results
+	IF ( LIBEDATASERVER1.2_LIBRARIES AND LIBEDATASERVER1.2_INCLUDE_DIRS AND _libedataserver1.2_FOUND )
+		SET( LIBEDATASERVER1.2_FOUND 1 )
+		IF ( NOT LibEDataServer1.2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libedataserver-1.2: ${LIBEDATASERVER1.2_LIBRARIES}" )
+		ENDIF ( NOT LibEDataServer1.2_FIND_QUIETLY )
+	ELSE ( LIBEDATASERVER1.2_LIBRARIES AND LIBEDATASERVER1.2_INCLUDE_DIRS AND _libedataserver1.2_FOUND )	
+		IF ( LibEDataServer1.2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libedataserver-1.2" )
+		ELSE ( LibEDataServer1.2_FIND_REQUIRED )
+			IF ( NOT LibEDataServer1.2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libedataserver-1.2" )	
+			ENDIF ( NOT LibEDataServer1.2_FIND_QUIETLY )
+		ENDIF ( LibEDataServer1.2_FIND_REQUIRED )
+	ENDIF ( LIBEDATASERVER1.2_LIBRARIES AND LIBEDATASERVER1.2_INCLUDE_DIRS AND _libedataserver1.2_FOUND )	
+
+ENDIF ( NOT LIBEDATASERVER1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBEDATASERVER1.2_LIBRARIES LIBEDATASERVER1.2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindEPackage.cmake b/cmake/modules/FindEPackage.cmake
new file mode 100644
index 0000000..1e34124
--- /dev/null
+++ b/cmake/modules/FindEPackage.cmake
@@ -0,0 +1,169 @@
+# - Try to find evolution-data-server components
+# Set evolution-data-server headers, libraries and the answer to all questions.
+#
+#  EVOLUTIONDATASERVER_INCLUDE_DIRS         Location of evolution-data-server headers 
+#  EVOLUTIONDATASERVER_LIBRARIES           List of libraries to use evolution-data-server
+#  EVOLUTIONDATASERVER_LIBRARY_DIRS           Pathes of libraries to use evolution-data-server
+#  EVOLUTIONDATASERVER_LDFLAGS           List of link flags to use evolution-data-server
+#
+#  LIBEBOOK_INCLUDE_DIRS         Location of libebook headers 
+#  LIBEBOOK_LIBRARIES           List of libraries to use libebook
+#  LIBEBOOK_LIBRARY_DIRS           Pathes of libraries to use libebook
+#  LIBEBOOK_LDFLAGS           List of link flags to use libebook
+#
+#  LIBECAL_INCLUDE_DIRS         Location of libecal headers 
+#  LIBECAL_LIBRARIES           List of libraries to use libecal
+#  LIBECAL_LIBRARY_DIRS           Pathes of libraries to use libecal
+#  LIBECAL_LDFLAGS           List of link flags to use libecal
+#
+#  LIBEDATABOOK_INCLUDE_DIRS         Location of libedata-book headers 
+#  LIBEDATABOOK_LIBRARIES           List of libraries to use libedata-book
+#  LIBEDATABOOK_LIBRARY_DIRS           Pathes of libraries to use libedata-book
+#  LIBEDATABOOK_LDFLAGS           List of link flags to use libedata-book
+#
+#  LIBEDATACAL_INCLUDE_DIRS         Location of libedata-cal headers 
+#  LIBEDATACAL_LIBRARIES           List of libraries to use libedata-cal
+#  LIBEDATACAL_LIBRARY_DIRS           Pathes of libraries to use libedata-cal
+#  LIBEDATACAL_LDFLAGS           List of link flags to use libedata-cal
+#
+#  LIBEDATASERVER_INCLUDE_DIRS         Location of libedataserver headers 
+#  LIBEDATASERVER_LIBRARIES           List of libraries to use libedataserver
+#  LIBEDATASERVER_LIBRARY_DIRS           Pathes of libraries to use libedataserver
+#  LIBEDATASERVER_LDFLAGS           List of link flags to use libedataserver
+#
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+FIND_PACKAGE ( EvolutionDataServer1.2 )
+FIND_PACKAGE ( EBook1.2 )
+FIND_PACKAGE ( ECal1.2 )
+FIND_PACKAGE ( EDataBook1.2 )
+FIND_PACKAGE ( EDataCal1.2 )
+FIND_PACKAGE ( EDataServer1.2 )
+IF ( EVOLUTIONDATASERVER1.2_LIBRARIES AND EVOLUTIONDATASERVER1.2_INCLUDE_DIRS )       
+	IF ( LIBEBOOK1.2_LIBRARIES AND LIBEBOOK1.2_INCLUDE_DIRS )       
+		IF ( LIBECAL1.2_LIBRARIES AND LIBECAL1.2_INCLUDE_DIRS ) 
+			IF ( LIBEDATABOOK1.2_LIBRARIES AND LIBEDATABOOK1.2_INCLUDE_DIRS )       
+				IF ( LIBEDATACAL1.2_LIBRARIES AND LIBEDATACAL1.2_INCLUDE_DIRS ) 
+					IF ( LIBEDATASERVER1.2_LIBRARIES AND LIBEDATASERVER1.2_INCLUDE_DIRS )   
+						SET( EDS1.2_FOUND 1 )
+					ELSE ( LIBEDATASERVER1.2_LIBRARIES AND LIBEDATASERVER1.2_INCLUDE_DIRS ) 
+						SET( EDS1.2_FOUND 0 )
+					ENDIF ( LIBEDATASERVER1.2_LIBRARIES AND LIBEDATASERVER1.2_INCLUDE_DIRS )        
+				ELSE ( LIBEDATACAL1.2_LIBRARIES AND LIBEDATACAL1.2_INCLUDE_DIRS )       
+					SET( EDS1.2_FOUND 0 )
+				ENDIF ( LIBEDATACAL1.2_LIBRARIES AND LIBEDATACAL1.2_INCLUDE_DIRS )      
+			ELSE ( LIBEDATABOOK1.2_LIBRARIES AND LIBEDATABOOK1.2_INCLUDE_DIRS )     
+				SET( EDS1.2_FOUND 0 )
+			ENDIF ( LIBEDATABOOK1.2_LIBRARIES AND LIBEDATABOOK1.2_INCLUDE_DIRS )    
+		ELSE ( LIBECAL1.2_LIBRARIES AND LIBECAL1.2_INCLUDE_DIRS )       
+			SET( EDS1.2_FOUND 0 )
+		ENDIF ( LIBECAL1.2_LIBRARIES AND LIBECAL1.2_INCLUDE_DIRS )      
+	ELSE ( LIBEBOOK1.2_LIBRARIES AND LIBEBOOK1.2_INCLUDE_DIRS )     
+		SET( EDS1.2_FOUND 0 )
+	ENDIF ( LIBEBOOK1.2_LIBRARIES AND LIBEBOOK1.2_INCLUDE_DIRS )    
+ELSE ( EVOLUTIONDATASERVER1.2_LIBRARIES AND EVOLUTIONDATASERVER1.2_INCLUDE_DIRS )     
+        SET( EDS1.2_FOUND 0 )
+ENDIF ( EVOLUTIONDATASERVER1.2_LIBRARIES AND EVOLUTIONDATASERVER1.2_INCLUDE_DIRS )    
+
+
+IF ( NOT EDS1.2_FOUND )
+	FIND_PACKAGE ( EvolutionDataServer1.0 )
+	FIND_PACKAGE ( EBook1.0 )
+	FIND_PACKAGE ( ECal1.0 )
+	FIND_PACKAGE ( EDataBook1.0 )
+	FIND_PACKAGE ( EDataCal1.0 )
+	FIND_PACKAGE ( EDataServer1.0 )
+	IF ( EVOLUTIONDATASERVER1.0_LIBRARIES AND EVOLUTIONDATASERVER1.0_INCLUDE_DIRS )       
+		IF ( LIBEBOOK1.0_LIBRARIES AND LIBEBOOK1.0_INCLUDE_DIRS )       
+			IF ( LIBECAL1.0_LIBRARIES AND LIBECAL1.0_INCLUDE_DIRS ) 
+				IF ( LIBEDATABOOK1.0_LIBRARIES AND LIBEDATABOOK1.0_INCLUDE_DIRS )       
+					IF ( LIBEDATACAL1.0_LIBRARIES AND LIBEDATACAL1.0_INCLUDE_DIRS ) 
+						IF ( LIBEDATASERVER1.0_LIBRARIES AND LIBEDATASERVER1.0_INCLUDE_DIRS )   
+							SET( EDS1.0_FOUND 1 )
+						ELSE ( LIBEDATASERVER1.0_LIBRARIES AND LIBEDATASERVER1.0_INCLUDE_DIRS ) 
+							SET( EDS1.0_FOUND 0 )
+						ENDIF ( LIBEDATASERVER1.0_LIBRARIES AND LIBEDATASERVER1.0_INCLUDE_DIRS )        
+					ELSE ( LIBEDATACAL1.0_LIBRARIES AND LIBEDATACAL1.0_INCLUDE_DIRS )       
+						SET( EDS1.0_FOUND 0 )
+					ENDIF ( LIBEDATACAL1.0_LIBRARIES AND LIBEDATACAL1.0_INCLUDE_DIRS )      
+				ELSE ( LIBEDATABOOK1.0_LIBRARIES AND LIBEDATABOOK1.0_INCLUDE_DIRS )     
+					SET( EDS1.0_FOUND 0 )
+				ENDIF ( LIBEDATABOOK1.0_LIBRARIES AND LIBEDATABOOK1.0_INCLUDE_DIRS )    
+			ELSE ( LIBECAL1.0_LIBRARIES AND LIBECAL1.0_INCLUDE_DIRS )       
+				SET( EDS1.0_FOUND 0 )
+			ENDIF ( LIBECAL1.0_LIBRARIES AND LIBECAL1.0_INCLUDE_DIRS )      
+		ELSE ( LIBEBOOK1.0_LIBRARIES AND LIBEBOOK1.0_INCLUDE_DIRS )     
+			SET( EDS1.0_FOUND 0 )
+		ENDIF ( LIBEBOOK1.0_LIBRARIES AND LIBEBOOK1.0_INCLUDE_DIRS )    
+	ELSE ( EVOLUTIONDATASERVER1.0_LIBRARIES AND EVOLUTIONDATASERVER1.0_INCLUDE_DIRS )     
+		SET( EDS1.0_FOUND 0 )
+	ENDIF ( EVOLUTIONDATASERVER1.0_LIBRARIES AND EVOLUTIONDATASERVER1.0_INCLUDE_DIRS )    
+ENDIF ( NOT EDS1.2_FOUND )
+
+
+
+
+IF ( EDS1.2_FOUND )
+  MESSAGE( STATUS "Evolution Data Server 1.2 used." )
+  SET( EVOLUTIONDATASERVER_INCLUDE_DIRS ${EVOLUTIONDATASERVER1.2_INCLUDE_DIRS} )
+  SET( EVOLUTIONDATASERVER_LIBRARIES ${EVOLUTIONDATASERVER1.2_LIBRARIES} )
+  SET( EVOLUTIONDATASERVER_LIBRARY_DIRS ${EVOLUTIONDATASERVER1.2_LIBRARY_DIRS} )
+  SET( EVOLUTIONDATASERVER_LDFLAGS ${EVOLUTIONDATASERVER1.2_LDFLAGS} )
+  SET( LIBEBOOK_INCLUDE_DIRS ${LIBEBOOK1.2_INCLUDE_DIRS} )
+  SET( LIBEBOOK_LIBRARIES ${LIBEBOOK1.2_LIBRARIES} )
+  SET( LIBEBOOK_LIBRARY_DIRS ${LIBEBOOK1.2_LIBRARY_DIRS} )
+  SET( LIBEBOOK_LDFLAGS ${LIBEBOOK1.2_LDFLAGS} )
+  SET( LIBECAL_INCLUDE_DIRS ${LIBECAL1.2_INCLUDE_DIRS} )
+  SET( LIBECAL_LIBRARIES ${LIBECAL1.2_LIBRARIES} )
+  SET( LIBECAL_LIBRARY_DIRS ${LIBECAL1.2_LIBRARY_DIRS} )
+  SET( LIBECAL_LDFLAGS ${LIBECAL1.2_LDFLAGS} )
+  SET( LIBEDATABOOK_INCLUDE_DIRS ${LIBEDATABOOK1.2_INCLUDE_DIRS} )
+  SET( LIBEDATABOOK_LIBRARIES ${LIBEDATABOOK1.2_LIBRARIES} )
+  SET( LIBEDATABOOK_LIBRARY_DIRS ${LIBEDATABOOK1.2_LIBRARY_DIRS} )
+  SET( LIBEDATABOOK_LDFLAGS ${LIBEDATABOOK1.2_LDFLAGS} )
+  SET( LIBEDATACAL_INCLUDE_DIRS ${LIBEDATACAL1.2_INCLUDE_DIRS} )
+  SET( LIBEDATACAL_LIBRARIES ${LIBEDATACAL1.2_LIBRARIES} )
+  SET( LIBEDATACAL_LIBRARY_DIRS ${LIBEDATACAL1.2_LIBRARY_DIRS} )
+  SET( LIBEDATACAL_LDFLAGS ${LIBEDATACAL1.2_LDFLAGS} )
+  SET( LIBEDATASERVER_INCLUDE_DIRS ${LIBEDATASERVER1.2_INCLUDE_DIRS} )
+  SET( LIBEDATASERVER_LIBRARIES ${LIBEDATASERVER1.2_LIBRARIES} )
+  SET( LIBEDATASERVER_LIBRARY_DIRS ${LIBEDATASERVER1.2_LIBRARY_DIRS} )
+  SET( LIBEDATASERVER_LDFLAGS ${LIBEDATASERVER1.2_LDFLAGS} )
+ELSE ( EDS1.2_FOUND )
+  IF ( EDS1.0_FOUND )
+    MESSAGE( STATUS "Evolution Data Server 1.0 used." )
+    SET( EVOLUTIONDATASERVER_INCLUDE_DIRS ${EVOLUTIONDATASERVER1.0_INCLUDE_DIRS} )
+    SET( EVOLUTIONDATASERVER_LIBRARIES ${EVOLUTIONDATASERVER1.2_LIBRARIES} )
+    SET( EVOLUTIONDATASERVER_LIBRARY_DIRS ${EVOLUTIONDATASERVER1.2_LIBRARY_DIRS} )
+    SET( EVOLUTIONDATASERVER_LDFLAGS ${EVOLUTIONDATASERVER1.2_LDFLAGS} )
+    SET( LIBEBOOK_INCLUDE_DIRS ${LIBEBOOK1.0_INCLUDE_DIRS} )
+    SET( LIBEBOOK_LIBRARIES ${LIBEBOOK1.0_LIBRARIES} )
+    SET( LIBEBOOK_LIBRARY_DIRS ${LIBEBOOK1.0_LIBRARY_DIRS} )
+    SET( LIBEBOOK_LDFLAGS ${LIBEBOOK1.0_LDFLAGS} )
+    SET( LIBECAL_INCLUDE_DIRS ${LIBECAL1.0_INCLUDE_DIRS} )
+    SET( LIBECAL_LIBRARIES ${LIBECAL1.0_LIBRARIES} )
+    SET( LIBECAL_LIBRARY_DIRS ${LIBECAL1.0_LIBRARY_DIRS} )
+    SET( LIBECAL_LDFLAGS ${LIBECAL1.0_LDFLAGS} )
+    SET( LIBEDATABOOK_INCLUDE_DIRS ${LIBEDATABOOK1.0_INCLUDE_DIRS} )
+    SET( LIBEDATABOOK_LIBRARIES ${LIBEDATABOOK1.0_LIBRARIES} )
+    SET( LIBEDATABOOK_LIBRARY_DIRS ${LIBEDATABOOK1.0_LIBRARY_DIRS} )
+    SET( LIBEDATABOOK_LDFLAGS ${LIBEDATABOOK1.0_LDFLAGS} )
+    SET( LIBEDATACAL_INCLUDE_DIRS ${LIBEDATACAL1.0_INCLUDE_DIRS} )
+    SET( LIBEDATACAL_LIBRARIES ${LIBEDATACAL1.0_LIBRARIES} )
+    SET( LIBEDATACAL_LIBRARY_DIRS ${LIBEDATACAL1.0_LIBRARY_DIRS} )
+    SET( LIBEDATACAL_LDFLAGS ${LIBEDATACAL1.0_LDFLAGS} )
+    SET( LIBEDATASERVER_INCLUDE_DIRS ${LIBEDATASERVER1.0_INCLUDE_DIRS} )
+    SET( LIBEDATASERVER_LIBRARIES ${LIBEDATASERVER1.0_LIBRARIES} )
+    SET( LIBEDATASERVER_LIBRARY_DIRS ${LIBEDATASERVER1.0_LIBRARY_DIRS} )
+    SET( LIBEDATASERVER_LDFLAGS ${LIBEDATASERVER1.0_LDFLAGS} )
+  ELSE ( EDS1.0_FOUND )
+    MESSAGE( FATAL_ERROR "Evolution Data Server not found." )
+  ENDIF ( EDS1.0_FOUND )
+ENDIF ( EDS1.2_FOUND )
+
diff --git a/cmake/modules/FindEvolutionDataServer1.0.cmake b/cmake/modules/FindEvolutionDataServer1.0.cmake
new file mode 100644
index 0000000..42fa3c7
--- /dev/null
+++ b/cmake/modules/FindEvolutionDataServer1.0.cmake
@@ -0,0 +1,67 @@
+# - Try to find evolutiondataserver1.0 components
+# Find evolutiondataserver 1.0 headers, libraries and the answer to all questions.
+#
+#  EVOLUTIONDATASERVER1.0_FOUND               True if evolutiondataserver1.0 got found
+#  EVOLUTIONDATASERVER1.0_INCLUDE_DIRS         Location of evolutiondataserver1.0 headers 
+#  EVOLUTIONDATASERVER1.0_LIBRARIES           List of libaries to use evolutiondataserver1.0
+#  EVOLUTIONDATASERVER1.0_DEFINITIONS         Definitions to compile evolutiondataserver1.0 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about evolution-data-server-1.0.pc settings
+IF ( EvolutionDataServer1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( EvolutionDataServer1.0_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( EvolutionDataServer1.0_FIND_REQUIRED )
+
+pkg_search_module( EVOLUTIONDATASERVER1.0 ${_pkgconfig_REQUIRED} evolution-data-server-1.0 )
+
+
+# Look for evolutiondataserver1.0 include dir and libraries w/o pkg-config.
+IF ( NOT EVOLUTIONDATASERVER1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+        # Handle dependencies
+	IF ( NOT LIBGNOME2_FOUND )
+		FIND_PACKAGE ( LibGnome2 REQUIRED )
+                IF ( LIBGNOME2_FOUND )
+                        SET ( EVOLUTIONDATASERVER1.0_INCLUDE_DIRS ${EVOLUTIONDATASERVER1.0_INCLUDE_DIRS} ${LIBGNOME2_INCLUDE_DIRS} )
+                        SET ( EVOLUTIONDATASERVER1.0_LIBRARIES ${EVOLUTIONDATASERVER1.0_LIBRARIES} ${LIBGNOME2_LIBRARIES} )
+                ENDIF ( LIBGNOME2_FOUND )		
+	ENDIF ( NOT LIBGNOME2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		SET ( BONOBO2_MIN_VERSION "2.4.2" )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( EVOLUTIONDATASERVER1.0_INCLUDE_DIRS ${EVOLUTIONDATASERVER1.0_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( EVOLUTIONDATASERVER1.0_LIBRARIES ${EVOLUTIONDATASERVER1.0_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+
+	# Report results
+	IF ( EVOLUTIONDATASERVER1.0_LIBRARIES AND EVOLUTIONDATASERVER1.0_INCLUDE_DIRS )
+		SET( EVOLUTIONDATASERVER1.0_FOUND 1 )
+		IF ( NOT EvolutionDataServer1.0_FIND_QUIETLY )
+			MESSAGE( STATUS "Found evolutiondataserver-1.0: ${EVOLUTIONDATASERVER1.0_LIBRARIES}" )
+		ENDIF ( NOT EvolutionDataServer1.0_FIND_QUIETLY )
+	ELSE ( EVOLUTIONDATASERVER1.0_LIBRARIES AND EVOLUTIONDATASERVER1.0_INCLUDE_DIRS )	
+		IF ( EvolutionDataServer1.0_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find evolutiondataserver-1.0" )
+		ELSE ( EvolutionDataServer1.0_FIND_REQUIRED )
+			IF ( NOT EvolutionDataServer1.0_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find evolutiondataserver-1.0" )	
+			ENDIF ( NOT EvolutionDataServer1.0_FIND_QUIETLY )
+		ENDIF ( EvolutionDataServer1.0_FIND_REQUIRED )
+	ENDIF ( EVOLUTIONDATASERVER1.0_LIBRARIES AND EVOLUTIONDATASERVER1.0_INCLUDE_DIRS )	
+
+ENDIF ( NOT EVOLUTIONDATASERVER1.0_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( EVOLUTIONDATASERVER1.0_LIBRARIES EVOLUTIONDATASERVER1.0_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindEvolutionDataServer1.2.cmake b/cmake/modules/FindEvolutionDataServer1.2.cmake
new file mode 100644
index 0000000..ab7f476
--- /dev/null
+++ b/cmake/modules/FindEvolutionDataServer1.2.cmake
@@ -0,0 +1,67 @@
+# - Try to find evolutiondataserver1.2 components
+# Find evolutiondataserver 1.2 headers, libraries and the answer to all questions.
+#
+#  EVOLUTIONDATASERVER1.2_FOUND               True if evolutiondataserver1.2 got found
+#  EVOLUTIONDATASERVER1.2_INCLUDE_DIRS         Location of evolutiondataserver1.2 headers 
+#  EVOLUTIONDATASERVER1.2_LIBRARIES           List of libaries to use evolutiondataserver1.2
+#  EVOLUTIONDATASERVER1.2_DEFINITIONS         Definitions to compile evolutiondataserver1.2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about evolution-data-server-1.2.pc settings
+IF ( EvolutionDataServer1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( EvolutionDataServer1.2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( EvolutionDataServer1.2_FIND_REQUIRED )
+
+pkg_search_module( EVOLUTIONDATASERVER1.2 ${_pkgconfig_REQUIRED} evolution-data-server-1.2 )
+
+
+# Look for evolutiondataserver1.2 include dir and libraries w/o pkg-config.
+IF ( NOT EVOLUTIONDATASERVER1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+        # Handle dependencies
+	IF ( NOT LIBGNOME2_FOUND )
+		FIND_PACKAGE ( LibGnome2 REQUIRED )
+                IF ( LIBGNOME2_FOUND )
+                        SET ( EVOLUTIONDATASERVER1.2_INCLUDE_DIRS ${EVOLUTIONDATASERVER1.2_INCLUDE_DIRS} ${LIBGNOME2_INCLUDE_DIRS} )
+                        SET ( EVOLUTIONDATASERVER1.2_LIBRARIES ${EVOLUTIONDATASERVER1.2_LIBRARIES} ${LIBGNOME2_LIBRARIES} )
+                ENDIF ( LIBGNOME2_FOUND )		
+	ENDIF ( NOT LIBGNOME2_FOUND )
+	IF ( NOT BONOBO2_FOUND )
+		SET ( BONOBO2_MIN_VERSION "2.4.2" )
+		FIND_PACKAGE ( BONOBO2 REQUIRED )
+                IF ( BONOBO2_FOUND )
+                        SET ( EVOLUTIONDATASERVER1.2_INCLUDE_DIRS ${EVOLUTIONDATASERVER1.2_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+                        SET ( EVOLUTIONDATASERVER1.2_LIBRARIES ${EVOLUTIONDATASERVER1.2_LIBRARIES} ${BONOBO2_LIBRARIES} )
+                ENDIF ( BONOBO2_FOUND )		
+	ENDIF ( NOT BONOBO2_FOUND )
+
+	# Report results
+	IF ( EVOLUTIONDATASERVER1.2_LIBRARIES AND EVOLUTIONDATASERVER1.2_INCLUDE_DIRS )
+		SET( EVOLUTIONDATASERVER1.2_FOUND 1 )
+		IF ( NOT EvolutionDataServer1.2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found evolutiondataserver-1.2: ${EVOLUTIONDATASERVER1.2_LIBRARIES}" )
+		ENDIF ( NOT EvolutionDataServer1.2_FIND_QUIETLY )
+	ELSE ( EVOLUTIONDATASERVER1.2_LIBRARIES AND EVOLUTIONDATASERVER1.2_INCLUDE_DIRS )	
+		IF ( EvolutionDataServer1.2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find evolutiondataserver-1.2" )
+		ELSE ( EvolutionDataServer1.2_FIND_REQUIRED )
+			IF ( NOT EvolutionDataServer1.2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find evolutiondataserver-1.2" )	
+			ENDIF ( NOT EvolutionDataServer1.2_FIND_QUIETLY )
+		ENDIF ( EvolutionDataServer1.2_FIND_REQUIRED )
+	ENDIF ( EVOLUTIONDATASERVER1.2_LIBRARIES AND EVOLUTIONDATASERVER1.2_INCLUDE_DIRS )	
+
+ENDIF ( NOT EVOLUTIONDATASERVER1.2_FOUND AND NOT PKG_CONFIG_FOUND )
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( EVOLUTIONDATASERVER1.2_LIBRARIES EVOLUTIONDATASERVER1.2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindExpat.cmake b/cmake/modules/FindExpat.cmake
new file mode 100644
index 0000000..974ddfd
--- /dev/null
+++ b/cmake/modules/FindExpat.cmake
@@ -0,0 +1,54 @@
+# - Try to find Expat 
+# Find Expat headers, libraries and the answer to all questions.
+#
+#  EXPAT_FOUND               True if Expat got found
+#  EXPAT_INCLUDE_DIRS        Location of Expat headers 
+#  EXPAT_LIBRARIES           List of libraries to use Expat 
+#
+#  Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+# WARNING: Currently Expat doesn't provide a .pc file
+#          Therefore it is not possible to use FindPkgConfig and to require a min version
+
+#INCLUDE( FindPkgConfig )
+
+#IF ( EXPAT_FIND_REQUIRED )
+#	SET( _pkgconfig_REQUIRED "REQUIRED" )
+#ELSE( EXPAT_FIND_REQUIRED )
+#	SET( _pkgconfig_REQUIRED "" )	
+#ENDIF ( EXPAT_FIND_REQUIRED )
+
+#IF ( EXPAT_MIN_VERSION )
+#	PKG_SEARCH_MODULE( EXPAT ${_pkgconfig_REQUIRED} expat>=${EXPAT_MIN_VERSION} )
+#ELSE ( EXPAT_MIN_VERSION )
+#	PKG_SEARCH_MODULE( EXPAT ${_pkgconfig_REQUIRED} expat )
+#ENDIF ( EXPAT_MIN_VERSION )
+
+
+#IF( NOT EXPAT_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( EXPAT_INCLUDE_DIRS expat.h)
+	FIND_LIBRARY( EXPAT_LIBRARIES expat )
+
+	# Report results
+	IF ( EXPAT_LIBRARIES AND EXPAT_INCLUDE_DIRS )	
+		SET( EXPAT_FOUND 1 )
+		IF ( NOT EXPAT_FIND_QUIETLY )
+			MESSAGE( STATUS "Found Expat: ${EXPAT_LIBRARIES}" )
+		ENDIF ( NOT EXPAT_FIND_QUIETLY )
+	ELSE ( EXPAT_LIBRARIES AND EXPAT_INCLUDE_DIRS )	
+		IF ( EXPAT_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find Expat" )
+		ELSE ( EXPAT_FIND_REQUIRED )
+			IF ( NOT EXPAT_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find Expat" )	
+			ENDIF ( NOT EXPAT_FIND_QUIETLY )
+		ENDIF ( EXPAT_FIND_REQUIRED )
+	ENDIF ( EXPAT_LIBRARIES AND EXPAT_INCLUDE_DIRS )
+#ENDIF( NOT EXPAT_FOUND AND NOT PKG_CONFIG_FOUND )
+
+MARK_AS_ADVANCED( EXPAT_LIBRARIES EXPAT_INCLUDE_DIRS )
\ No newline at end of file
diff --git a/cmake/modules/FindGConf2.cmake b/cmake/modules/FindGConf2.cmake
new file mode 100644
index 0000000..867601b
--- /dev/null
+++ b/cmake/modules/FindGConf2.cmake
@@ -0,0 +1,87 @@
+# - Try to find gconf2 
+# Find gconf2 headers, libraries and the answer to all questions.
+#
+#  GCONF2_FOUND               True if gconf2 got found
+#  GCONF2_INCLUDEDIR          Location of gconf2 headers 
+#  GCONF2_LIBRARIES           List of libaries to use gconf2
+#  GCONF2_DEFINITIONS         Definitions to compile gconf2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about gconf-2.0.pc settings
+IF ( GConf2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( GConf2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( GConf2_FIND_REQUIRED )
+
+pkg_search_module( GCONF2 ${_pkgconfig_REQUIRED} gconf-2.0 )
+
+
+# Look for gconf2 include dir and libraries w/o pkgconfig
+IF ( NOT GCONF2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _gconf2_include_DIR gconf/gconf.h PATH_SUFFIXES gconf/2 
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+	)
+	FIND_LIBRARY( _gconf2_link_DIR gconf-2
+		PATHS
+		/opt/local/lib
+		/sw/lib
+		/usr/lib
+		/usr/local/lib
+		/usr/lib64
+		/usr/local/lib64
+		/opt/lib64
+	)
+	IF ( _gconf2_include_DIR AND _gconf2_link_DIR )
+		SET ( _gconf2_FOUND TRUE )
+	ENDIF ( _gconf2_include_DIR AND _gconf2_link_DIR )
+
+
+	IF ( _gconf2_FOUND )
+		SET ( GCONF2_INCLUDE_DIRS ${_gconf2_include_DIR} )
+		SET ( GCONF2_LIBRARIES ${_gconf2_link_DIR} )
+	ENDIF ( _gconf2_FOUND )
+
+	# Handle dependencies
+	IF ( NOT ORBIT2_FOUND )
+		FIND_PACKAGE( ORBit2 REQUIRED)
+		IF ( ORBIT2_FOUND )
+			SET ( GCONF2_INCLUDE_DIRS ${GCONF2_INCLUDE_DIRS} ${ORBIT2_INCLUDE_DIRS} )
+			SET ( GCONF2_LIBRARIES ${GCONF2_LIBRARIES} ${ORBIT2_LIBRARIES} )
+		ENDIF ( ORBIT2_FOUND )
+	ENDIF ( NOT ORBIT2_FOUND )
+
+	# Report results
+	IF ( GCONF2_LIBRARIES AND GCONF2_INCLUDE_DIRS AND _gconf2_FOUND )	
+		SET( GCONF2_FOUND 1 )
+		IF ( NOT GConf2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found gconf2: ${GCONF2_LIBRARIES} ${GCONF2_INCLUDE_DIRS}" )
+		ENDIF ( NOT GConf2_FIND_QUIETLY )
+	ELSE ( GCONF2_LIBRARIES AND GCONF2_INCLUDE_DIRS AND _gconf2_FOUND )	
+		IF ( GConf2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find gconf2" )
+		ELSE ( GConf2_FIND_REQUIRED )
+			IF ( NOT GConf2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find gconf2" )	
+			ENDIF ( NOT GConf2_FIND_QUIETLY )
+		ENDIF ( GConf2_FIND_REQUIRED )
+	ENDIF ( GCONF2_LIBRARIES AND GCONF2_INCLUDE_DIRS AND _gconf2_FOUND )	
+
+ENDIF ( NOT GCONF2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( GCONF2_LIBRARIES GCONF2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindGLIB2.cmake b/cmake/modules/FindGLIB2.cmake
new file mode 100644
index 0000000..87bf6ec
--- /dev/null
+++ b/cmake/modules/FindGLIB2.cmake
@@ -0,0 +1,235 @@
+# - Try to find GLib2
+# Once done this will define
+#
+#  GLIB2_FOUND - system has GLib2
+#  GLIB2_INCLUDE_DIRS - the GLib2 include directory
+#  GLIB2_LIBRARIES - Link these to use GLib2
+#
+#  HAVE_GLIB_GREGEX_H  glib has gregex.h header and 
+#                      supports g_regex_match_simple
+#
+#  Copyright (c) 2006 Andreas Schneider 
+#  Copyright (c) 2006 Philippe Bernery 
+#  Copyright (c) 2007 Daniel Gollub 
+#  Copyright (c) 2007 Alban Browaeys 
+#  Copyright (c) 2008 Michael Bell 
+#  Copyright (c) 2008-2009 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+IF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS )
+  # in cache already
+  SET(GLIB2_FOUND TRUE)
+ELSE (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS )
+
+  INCLUDE(FindPkgConfig)
+
+  ## Glib
+  IF ( GLIB2_FIND_REQUIRED )
+    SET( _pkgconfig_REQUIRED "REQUIRED" )
+  ELSE ( GLIB2_FIND_REQUIRED )
+    SET( _pkgconfig_REQUIRED "" )
+  ENDIF ( GLIB2_FIND_REQUIRED )
+
+  IF ( GLIB2_MIN_VERSION )
+    PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0>=${GLIB2_MIN_VERSION} )
+  ELSE ( GLIB2_MIN_VERSION )
+    PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0 )
+  ENDIF ( GLIB2_MIN_VERSION )
+  IF ( PKG_CONFIG_FOUND )
+    IF ( GLIB2_FOUND )
+      SET ( GLIB2_CORE_FOUND TRUE )
+    ELSE ( GLIB2_FOUND )
+      SET ( GLIB2_CORE_FOUND FALSE )
+    ENDIF ( GLIB2_FOUND )
+  ENDIF ( PKG_CONFIG_FOUND )
+
+  # Look for glib2 include dir and libraries w/o pkgconfig
+  IF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND )
+    FIND_PATH(
+      _glibconfig_include_DIR
+    NAMES
+      glibconfig.h
+    PATHS
+      /opt/gnome/lib64
+      /opt/gnome/lib
+      /opt/lib/
+      /opt/local/lib
+      /sw/lib/
+      /usr/lib64
+      /usr/lib
+      /usr/local/include
+      ${CMAKE_LIBRARY_PATH}
+    PATH_SUFFIXES
+      glib-2.0/include
+    )
+
+    FIND_PATH(
+      _glib2_include_DIR
+    NAMES
+      glib.h
+    PATHS
+      /opt/gnome/include
+      /opt/local/include
+      /sw/include
+      /usr/include
+      /usr/local/include
+    PATH_SUFFIXES
+      glib-2.0
+    )
+
+    #MESSAGE(STATUS "Glib headers: ${_glib2_include_DIR}")
+
+    FIND_LIBRARY(
+      _glib2_link_DIR
+    NAMES
+      glib-2.0
+      glib
+    PATHS
+      /opt/gnome/lib
+      /opt/local/lib
+      /sw/lib
+      /usr/lib
+      /usr/local/lib
+    )
+    IF ( _glib2_include_DIR AND _glib2_link_DIR )
+        SET ( _glib2_FOUND TRUE )
+    ENDIF ( _glib2_include_DIR AND _glib2_link_DIR )
+
+
+    IF ( _glib2_FOUND )
+        SET ( GLIB2_INCLUDE_DIRS ${_glib2_include_DIR} ${_glibconfig_include_DIR} )
+        SET ( GLIB2_LIBRARIES ${_glib2_link_DIR} )
+        SET ( GLIB2_CORE_FOUND TRUE )
+    ELSE ( _glib2_FOUND )
+        SET ( GLIB2_CORE_FOUND FALSE )
+    ENDIF ( _glib2_FOUND )
+
+    # Handle dependencies
+    # libintl
+    IF ( NOT LIBINTL_FOUND )
+      FIND_PATH(LIBINTL_INCLUDE_DIR
+      NAMES
+        libintl.h
+      PATHS
+        /opt/gnome/include
+        /opt/local/include
+        /sw/include
+        /usr/include
+        /usr/local/include
+      )
+
+      FIND_LIBRARY(LIBINTL_LIBRARY
+      NAMES
+        intl
+      PATHS
+        /opt/gnome/lib
+        /opt/local/lib
+        /sw/lib
+        /usr/local/lib
+        /usr/lib
+      )
+
+      IF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR)
+        SET (LIBINTL_FOUND TRUE)
+      ENDIF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR)
+    ENDIF ( NOT LIBINTL_FOUND )
+
+    # libiconv
+    IF ( NOT LIBICONV_FOUND )
+      FIND_PATH(LIBICONV_INCLUDE_DIR
+      NAMES
+        iconv.h
+      PATHS
+        /opt/gnome/include
+        /opt/local/include
+        /opt/local/include
+        /sw/include
+        /sw/include
+        /usr/local/include
+        /usr/include
+      PATH_SUFFIXES
+        glib-2.0
+      )
+
+      FIND_LIBRARY(LIBICONV_LIBRARY
+      NAMES
+        iconv
+      PATHS
+        /opt/gnome/lib
+        /opt/local/lib
+        /sw/lib
+        /usr/lib
+        /usr/local/lib
+      )
+
+      IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR)
+        SET (LIBICONV_FOUND TRUE)
+      ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR)
+    ENDIF ( NOT LIBICONV_FOUND )
+
+    IF (LIBINTL_FOUND)
+      SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBINTL_LIBRARY})
+      SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBINTL_INCLUDE_DIR})
+    ENDIF (LIBINTL_FOUND)
+
+    IF (LIBICONV_FOUND)
+      SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY})
+      SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR})
+    ENDIF (LIBICONV_FOUND)
+
+  ENDIF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND )
+  ##
+
+  IF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES)
+    SET (GLIB2_FOUND TRUE)
+  ENDIF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES)
+
+  IF (GLIB2_FOUND)
+    IF (NOT GLIB2_FIND_QUIETLY)
+      MESSAGE (STATUS "Found GLib2: ${GLIB2_LIBRARIES} ${GLIB2_INCLUDE_DIRS}")
+    ENDIF (NOT GLIB2_FIND_QUIETLY)
+  ELSE (GLIB2_FOUND)
+    IF (GLIB2_FIND_REQUIRED)
+      MESSAGE (SEND_ERROR "Could not find GLib2")
+    ENDIF (GLIB2_FIND_REQUIRED)
+  ENDIF (GLIB2_FOUND)
+
+  # show the GLIB2_INCLUDE_DIRS and GLIB2_LIBRARIES variables only in the advanced view
+  MARK_AS_ADVANCED(GLIB2_INCLUDE_DIRS GLIB2_LIBRARIES)
+  MARK_AS_ADVANCED(LIBICONV_INCLUDE_DIR LIBICONV_LIBRARY)
+  MARK_AS_ADVANCED(LIBINTL_INCLUDE_DIR LIBINTL_LIBRARY)
+
+ENDIF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS)
+
+IF ( WIN32 )
+    # include libiconv for win32
+    IF ( NOT LIBICONV_FOUND )
+      FIND_PATH(LIBICONV_INCLUDE_DIR iconv.h PATH_SUFFIXES glib-2.0)
+
+      FIND_LIBRARY(LIBICONV_LIBRARY NAMES iconv)
+
+      IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR)
+        SET (LIBICONV_FOUND TRUE)
+      ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR)
+    ENDIF ( NOT LIBICONV_FOUND )
+    IF (LIBICONV_FOUND)
+      SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY})
+      SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR})
+    ENDIF (LIBICONV_FOUND)
+ENDIF ( WIN32 )
+
+IF ( GLIB2_FOUND )
+	# Check if system has a newer version of glib
+	# which supports g_regex_match_simple
+	INCLUDE( CheckIncludeFiles )
+	SET( CMAKE_REQUIRED_INCLUDES ${GLIB2_INCLUDE_DIRS} )
+	CHECK_INCLUDE_FILES ( glib/gregex.h HAVE_GLIB_GREGEX_H )
+	CHECK_INCLUDE_FILES ( glib/gchecksum.h HAVE_GLIB_GCHECKSUM_H )
+	# Reset CMAKE_REQUIRED_INCLUDES
+	SET( CMAKE_REQUIRED_INCLUDES "" )
+ENDIF( GLIB2_FOUND )
diff --git a/cmake/modules/FindGMODULE2.cmake b/cmake/modules/FindGMODULE2.cmake
new file mode 100644
index 0000000..a367660
--- /dev/null
+++ b/cmake/modules/FindGMODULE2.cmake
@@ -0,0 +1,56 @@
+# - Try to find GModule2 
+# Find GModule headers, libraries and the answer to all questions.
+#
+#  GMODULE2_FOUND               True if GMODULE2 got found
+#  GMODULE2_INCLUDE_DIRS        Location of GMODULE2 headers 
+#  GMODULE2_LIBRARIES           List of libraries to use GMODULE2 
+#
+#  Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( GMODULE2_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( GMODULE2_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( GMODULE2_FIND_REQUIRED )
+
+IF ( GMODULE2_MIN_VERSION )
+	PKG_SEARCH_MODULE( GMODULE2 ${_pkgconfig_REQUIRED} gmodule-2.0>=${GMODULE2_MIN_VERSION} )
+ELSE ( GMODULE2_MIN_VERSION )
+	PKG_SEARCH_MODULE( GMODULE2 ${_pkgconfig_REQUIRED} gmodule-2.0 )
+ENDIF ( GMODULE2_MIN_VERSION )
+
+
+IF( NOT GMODULE2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( GMODULE2_INCLUDE_DIRS gmodule.h PATH_SUFFIXES glib-2.0 )
+
+	IF ( APPLE )
+		FIND_LIBRARY( GMODULE2_LIBRARIES glib )
+	ELSE ( APPLE )
+		FIND_LIBRARY( GMODULE2_LIBRARIES NAMES gmodule-2.0 gmodule )
+	ENDIF (APPLE)
+
+	# Report results
+	IF ( GMODULE2_LIBRARIES AND GMODULE2_INCLUDE_DIRS )	
+		SET( GMODULE2_FOUND 1 )
+		IF ( NOT GMODULE2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found GMODULE2: ${GMODULE2_LIBRARIES} ${GMODULE2_INCLUDE_DIRS}" )
+		ENDIF ( NOT GMODULE2_FIND_QUIETLY )
+	ELSE ( GMODULE2_LIBRARIES AND GMODULE2_INCLUDE_DIRS )	
+		IF ( GMODULE2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find GMODULE2" )
+		ELSE ( GMODULE2_FIND_REQUIRED )
+			IF ( NOT GMODULE2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find GMODULE2" )	
+			ENDIF ( NOT GMODULE2_FIND_QUIETLY )
+		ENDIF ( GMODULE2_FIND_REQUIRED )
+	ENDIF ( GMODULE2_LIBRARIES AND GMODULE2_INCLUDE_DIRS )
+ENDIF( NOT GMODULE2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+MARK_AS_ADVANCED( GMODULE2_LIBRARIES GMODULE2_INCLUDE_DIRS )
\ No newline at end of file
diff --git a/cmake/modules/FindGNOKII.cmake b/cmake/modules/FindGNOKII.cmake
new file mode 100644
index 0000000..61f2e4b
--- /dev/null
+++ b/cmake/modules/FindGNOKII.cmake
@@ -0,0 +1,55 @@
+# - Try to find GNOKII
+# Find GNOKII headers, libraries and the answer to all questions.
+#
+#  GNOKII_FOUND               True if GNOKII got found
+#  GNOKII_INCLUDE_DIRS        Location of GNOKII headers 
+#  GNOKII_LIBRARIES           List of libaries to use GNOKII
+#  GNOKII_DEFINITIONS         Definitions to compile GNOKII 
+#
+#  Copyright (c) 2007 Daniel Gollub 
+#  Copyright (c) 2008 Bjoern Ricks  
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#	
+
+INCLUDE( FindPkgConfig )
+
+IF ( GNOKII_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( GNOKII_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( GNOKII_FIND_REQUIRED )
+
+IF ( GNOKII_MIN_VERSION )
+	PKG_SEARCH_MODULE( GNOKII ${_pkgconfig_REQUIRED} gnokii>=${GNOKII_MIN_VERSION} )
+ELSE ( GNOKII_MIN_VERSION )
+	PKG_SEARCH_MODULE( GNOKII ${_pkgconfig_REQUIRED} gnokii )
+ENDIF ( GNOKII_MIN_VERSION )
+
+
+IF( NOT GNOKII_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( GNOKII_INCLUDE_DIRS gnokii.h )
+	FIND_LIBRARY( GNOKII_LIBRARIES gnokii)
+
+	# Report results
+	IF ( GNOKII_LIBRARIES AND GNOKII_INCLUDE_DIRS )	
+		SET( GNOKII_FOUND 1 )
+		IF ( NOT GNOKII_FIND_QUIETLY )
+			MESSAGE( STATUS "Found GNOKII: ${GNOKII_LIBRARIES}" )
+		ENDIF ( NOT GNOKII_FIND_QUIETLY )
+	ELSE ( GNOKII_LIBRARIES AND GNOKII_INCLUDE_DIRS )	
+		IF ( GNOKII_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find GNOKII" )
+		ELSE ( GNOKII_FIND_REQUIRED )
+			IF ( NOT GNOKII_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find GNOKII" )	
+			ENDIF ( NOT GNOKII_FIND_QUIETLY )
+		ENDIF ( GNOKII_FIND_REQUIRED )
+	ENDIF ( GNOKII_LIBRARIES AND GNOKII_INCLUDE_DIRS )
+ENDIF( NOT GNOKII_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( GNOKII_LIBRARIES GNOKII_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindGNUTLS.cmake b/cmake/modules/FindGNUTLS.cmake
new file mode 100644
index 0000000..7fbb9de
--- /dev/null
+++ b/cmake/modules/FindGNUTLS.cmake
@@ -0,0 +1,51 @@
+# - Try to find GNUTLS 
+# Find GNUTLS headers, libraries and the answer to all questions.
+#
+#  GNUTLS_FOUND               True if gnutls got found
+#  GNUTLS_INCLUDE_DIRS        Location of gnutls headers 
+#  GNUTLS_LIBRARIES           List of libaries to use gnutls 
+#
+# Copyright (c) 2007 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( GNUTLS_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( GNUTLS_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( GNUTLS_FIND_REQUIRED )
+
+IF ( GNUTLS_MIN_VERSION )
+	PKG_SEARCH_MODULE( GNUTLS ${_pkgconfig_REQUIRED} gnutls>=${GNUTLS_MIN_VERSION} )
+ELSE ( GNUTLS_MIN_VERSION )
+	PKG_SEARCH_MODULE( GNUTLS ${_pkgconfig_REQUIRED} gnutls )
+ENDIF ( GNUTLS_MIN_VERSION )
+
+
+IF( NOT GNUTLS_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( GNUTLS_INCLUDE_DIRS gnutls/gnutls.h )
+	FIND_LIBRARY( GNUTLS_LIBRARIES gnutls)
+
+	# Report results
+	IF ( GNUTLS_LIBRARIES AND GNUTLS_INCLUDE_DIRS )	
+		SET( GNUTLS_FOUND 1 )
+		IF ( NOT GNUTLS_FIND_QUIETLY )
+			MESSAGE( STATUS "Found gnutls: ${GNUTLS_LIBRARIES}" )
+		ENDIF ( NOT GNUTLS_FIND_QUIETLY )
+	ELSE ( GNUTLS_LIBRARIES AND GNUTLS_INCLUDE_DIRS )	
+		IF ( GNUTLS_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find gnutls" )
+		ELSE ( GNUTLS_FIND_REQUIRED )
+			IF ( NOT GNUTLS_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find gnutls" )	
+			ENDIF ( NOT GNUTLS_FIND_QUIETLY )
+		ENDIF ( GNUTLS_FIND_REQUIRED )
+	ENDIF ( GNUTLS_LIBRARIES AND GNUTLS_INCLUDE_DIRS )
+ENDIF( NOT GNUTLS_FOUND AND NOT PKG_CONFIG_FOUND )
+
+MARK_AS_ADVANCED( GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIRS )
diff --git a/cmake/modules/FindGOBJECT2.cmake b/cmake/modules/FindGOBJECT2.cmake
new file mode 100644
index 0000000..d0d4cda
--- /dev/null
+++ b/cmake/modules/FindGOBJECT2.cmake
@@ -0,0 +1,51 @@
+# - Try to find GObject2 
+# Find GObject2 headers, libraries and the answer to all questions.
+#
+#  GOBJECT2_FOUND               True if GOBJECT2 got found
+#  GOBJECT2_INCLUDE_DIRS        Location of GOBJECT2 headers 
+#  GOBJECT2_LIBRARIES           List of libraries to use GOBJECT2 
+#
+# Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( GOBJECT2_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( GOBJECT2_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( GOBJECT2_FIND_REQUIRED )
+
+IF ( GOBJECT2_MIN_VERSION )
+	PKG_SEARCH_MODULE( GOBJECT2 ${_pkgconfig_REQUIRED} gobject-2.0>=${GOBJECT2_MIN_VERSION} )
+ELSE ( GOBJECT2_MIN_VERSION )
+	PKG_SEARCH_MODULE( GOBJECT2 ${_pkgconfig_REQUIRED} gobject-2.0 )
+ENDIF ( GOBJECT2_MIN_VERSION )
+
+
+IF( NOT GOBJECT2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( GOBJECT2_INCLUDE_DIRS gobject/gobject.h PATH_SUFFIXES glib-2.0)
+	FIND_LIBRARY( GOBJECT2_LIBRARIES gobject-2.0 )
+
+	# Report results
+	IF ( GOBJECT2_LIBRARIES AND GOBJECT2_INCLUDE_DIRS )	
+		SET( GOBJECT2_FOUND 1 )
+		IF ( NOT GOBJECT2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found GOBJECT2: ${GOBJECT2_LIBRARIES}" )
+		ENDIF ( NOT GOBJECT2_FIND_QUIETLY )
+	ELSE ( GOBJECT2_LIBRARIES AND GOBJECT2_INCLUDE_DIRS )	
+		IF ( GOBJECT2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find GOBJECT2" )
+		ELSE ( GOBJECT2_FIND_REQUIRED )
+			IF ( NOT GOBJECT2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find GOBJECT2" )	
+			ENDIF ( NOT GOBJECT2_FIND_QUIETLY )
+		ENDIF ( GOBJECT2_FIND_REQUIRED )
+	ENDIF ( GOBJECT2_LIBRARIES AND GOBJECT2_INCLUDE_DIRS )
+ENDIF( NOT GOBJECT2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+MARK_AS_ADVANCED( GOBJECT2_LIBRARIES GOBJECT2_INCLUDE_DIRS )
diff --git a/cmake/modules/FindGTHREAD2.cmake b/cmake/modules/FindGTHREAD2.cmake
new file mode 100644
index 0000000..1618fd3
--- /dev/null
+++ b/cmake/modules/FindGTHREAD2.cmake
@@ -0,0 +1,58 @@
+# - Try to find GThread2 
+# Find GThread headers, libraries and the answer to all questions.
+#
+#  GTHREAD2_FOUND               True if GTHREAD2 got found
+#  GTHREAD2_INCLUDE_DIRS        Location of GTHREAD2 headers 
+#  GTHREAD2_LIBRARIES           List of libraries to use GTHREAD2 
+#
+#  Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( GTHREAD2_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( GTHREAD2_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( GTHREAD2_FIND_REQUIRED )
+
+IF ( GTHREAD2_MIN_VERSION )
+	PKG_SEARCH_MODULE( GTHREAD2 ${_pkgconfig_REQUIRED} gthread-2.0>=${GTHREAD2_MIN_VERSION} )
+ELSE ( GTHREAD2_MIN_VERSION )
+	PKG_SEARCH_MODULE( GTHREAD2 ${_pkgconfig_REQUIRED} gthread-2.0 )
+ENDIF ( GTHREAD2_MIN_VERSION )
+
+
+IF( NOT GTHREAD2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( GTHREAD2_INCLUDE_DIRS gthread.h PATH_SUFFIXES glib-2.0/glib GLib.framework/Headers/glib )
+	IF ( APPLE ) 
+		FIND_LIBRARY( GTHREAD2_LIBRARIES glib )
+	ELSE ( APPLE )
+		FIND_LIBRARY( GTHREAD2_LIBRARIES gthread-2.0 )
+	ENDIF ( APPLE )
+	
+	#MESSAGE( STATUS "Gthread headers: ${GTHREAD2_INCLUDE_DIRS}" )
+	#MESSAGE( STATUS "Gthread libs: ${GTHREAD2_LIBRARIES}" )
+	
+	# Report results
+	IF ( GTHREAD2_LIBRARIES AND GTHREAD2_INCLUDE_DIRS )	
+		SET( GTHREAD2_FOUND 1 )
+		IF ( NOT GTHREAD2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found GTHREAD2: ${GTHREAD2_LIBRARIES} ${GTHREAD2_INCLUDE_DIRS}" )
+		ENDIF ( NOT GTHREAD2_FIND_QUIETLY )
+	ELSE ( GTHREAD2_LIBRARIES AND GTHREAD2_INCLUDE_DIRS )	
+		IF ( GTHREAD2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find GTHREAD2" )
+		ELSE ( GTHREAD2_FIND_REQUIRED )
+			IF ( NOT GTHREAD2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find GTHREAD2" )	
+			ENDIF ( NOT GTHREAD2_FIND_QUIETLY )
+		ENDIF ( GTHREAD2_FIND_REQUIRED )
+	ENDIF ( GTHREAD2_LIBRARIES AND GTHREAD2_INCLUDE_DIRS )
+ENDIF( NOT GTHREAD2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+MARK_AS_ADVANCED( GTHREAD2_LIBRARIES GTHREAD2_INCLUDE_DIRS )
diff --git a/cmake/modules/FindGTK2.cmake b/cmake/modules/FindGTK2.cmake
new file mode 100644
index 0000000..39094b9
--- /dev/null
+++ b/cmake/modules/FindGTK2.cmake
@@ -0,0 +1,452 @@
+# - Try to find GTK2
+# Once done this will define
+#
+#  GTK2_FOUND - System has Boost
+#  GTK2_INCLUDE_DIRS - GTK2 include directory
+#  GTK2_LIBRARIES - Link these to use GTK2
+#  GTK2_LIBRARY_DIRS - The path to where the GTK2 library files are.
+#  GTK2_DEFINITIONS - Compiler switches required for using GTK2
+#
+#  Copyright (c) 2007 Andreas Schneider 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+set(GTK2_DEBUG ON)
+
+macro(GTK2_DEBUG_MESSAGE _message)
+  if (GTK2_DEBUG)
+    message(STATUS "(DEBUG) ${_message}")
+  endif (GTK2_DEBUG)
+endmacro(GTK2_DEBUG_MESSAGE _message)
+
+if (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS)
+  # in cache already
+  set(GTK2_FOUND TRUE)
+else (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS)
+  if (UNIX)
+    # use pkg-config to get the directories and then use these values
+    # in the FIND_PATH() and FIND_LIBRARY() calls
+    include(UsePkgConfig)
+
+    pkgconfig(gtk+-2.0 _GTK2IncDir _GTK2LinkDir _GTK2LinkFlags _GTK2Cflags)
+
+    find_path(GTK2_GTK_INCLUDE_DIR
+      NAMES
+        gtk/gtk.h
+      PATHS
+        $ENV{GTK2_HOME}
+        ${_GTK2IncDir}
+        /usr/include/gtk-2.0
+        /usr/local/include/gtk-2.0
+        /opt/include/gtk-2.0
+        /opt/gnome/include/gtk-2.0
+        /sw/include/gtk-2.0
+    )
+    gtk2_debug_message("GTK2_GTK_INCLUDE_DIR is ${GTK2_GTK_INCLUDE_DIR}")
+
+    # Some Linux distributions (e.g. Red Hat) have glibconfig.h
+    # and glib.h in different directories, so we need to look
+    # for both.
+    #  - Atanas Georgiev 
+    pkgconfig(glib-2.0 _GLIB2IncDir _GLIB2LinkDir _GLIB2LinkFlags _GLIB2Cflags)
+    pkgconfig(gmodule-2.0 _GMODULE2IncDir _GMODULE2LinkDir _GMODULE2LinkFlags _GMODULE2Cflags)
+
+    find_path(GTK2_GLIBCONFIG_INCLUDE_DIR
+      NAMES
+        glibconfig.h
+      PATHS
+        ${_GLIB2IncDir}
+        ${_GMODULE2IncDir}
+        /opt/gnome/lib64/glib-2.0/include
+        /opt/gnome/lib/glib-2.0/include
+        /opt/lib/glib-2.0/include
+        /usr/lib64/glib-2.0/include
+        /usr/lib/glib-2.0/include
+        /sw/lib/glib-2.0/include
+    )
+    gtk2_debug_message("GTK2_GLIBCONFIG_INCLUDE_DIR is ${GTK2_GLIBCONFIG_INCLUDE_DIR}")
+
+    find_path(GTK2_GLIB_INCLUDE_DIR
+      NAMES
+        glib.h
+      PATHS
+        ${_GLIB2IncDir}
+        ${_GMODULE2IncDir}
+        /opt/include/glib-2.0
+        /opt/gnome/include/glib-2.0
+        /usr/include/glib-2.0
+        /sw/include/glib-2.0
+    )
+    gtk2_debug_message("GTK2_GLIB_INCLUDE_DIR is ${GTK2_GLIB_INCLUDE_DIR}")
+
+    pkgconfig(gdk-2.0 _GDK2IncDir _GDK2LinkDir _GDK2LinkFlags _GDK2Cflags)
+
+    find_path(GTK2_GDK_INCLUDE_DIR
+      NAMES
+        gdkconfig.h
+      PATHS
+        ${_GDK2IncDir}
+        /opt/gnome/lib/gtk-2.0/include
+        /opt/gnome/lib64/gtk-2.0/include
+        /opt/lib/gtk-2.0/include
+        /usr/lib/gtk-2.0/include
+        /usr/lib64/gtk-2.0/include
+        /sw/lib/gtk-2.0/include
+    )
+    gtk2_debug_message("GTK2_GDK_INCLUDE_DIR is ${GTK2_GDK_INCLUDE_DIR}")
+
+    find_path(GTK2_GTKGL_INCLUDE_DIR
+      NAMES
+        gtkgl/gtkglarea.h
+      PATHS
+        ${_GLIB2IncDir}
+        /usr/include
+        /usr/local/include
+        /usr/openwin/share/include
+        /opt/gnome/include
+        /opt/include
+        /sw/include
+    )
+    gtk2_debug_message("GTK2_GTKGL_INCLUDE_DIR is ${GTK2_GTKGL_INCLUDE_DIR}")
+
+    pkgconfig(libglade-2.0 _GLADEIncDir _GLADELinkDir _GLADELinkFlags _GLADECflags)
+
+    find_path(GTK2_GLADE_INCLUDE_DIR
+      NAMES
+        glade/glade.h
+      PATHS
+        ${_GLADEIncDir}
+        /opt/gnome/include/libglade-2.0
+        /usr/include/libglade-2.0
+        /opt/include/libglade-2.0
+        /sw/include/libglade-2.0
+    )
+    gtk2_debug_message("GTK2_GLADE_INCLUDE_DIR is ${GTK2_GLADE_INCLUDE_DIR}")
+
+    pkgconfig(pango _PANGOIncDir _PANGOLinkDir _PANGOLinkFlags _PANGOCflags)
+
+    find_path(GTK2_PANGO_INCLUDE_DIR
+      NAMES
+        pango/pango.h
+      PATHS
+        ${_PANGOIncDir}
+        /usr/include/pango-1.0
+        /opt/gnome/include/pango-1.0
+        /opt/include/pango-1.0
+        /sw/include/pango-1.0
+    )
+    gtk2_debug_message("GTK2_PANGO_INCLUDE_DIR is ${GTK2_PANGO_INCLUDE_DIR}")
+
+    pkgconfig(cairo _CAIROIncDir _CAIROLinkDir _CAIROLinkFlags _CAIROCflags)
+
+    find_path(GTK2_CAIRO_INCLUDE_DIR
+      NAMES
+        cairo.h
+      PATHS
+        ${_CAIROIncDir}
+        /opt/gnome/include/cairo
+        /usr/include
+        /usr/include/cairo
+        /opt/include
+        /opt/include/cairo
+        /sw/include
+        /sw/include/cairo
+    )
+    gtk2_debug_message("GTK2_CAIRO_INCLUDE_DIR is ${GTK2_CAIRO_INCLUDE_DIR}")
+
+    pkgconfig(atk _ATKIncDir _ATKLinkDir _ATKLinkFlags _ATKCflags)
+
+    find_path(GTK2_ATK_INCLUDE_DIR
+      NAMES
+        atk/atk.h
+      PATHS
+        ${_ATKIncDir}
+        /opt/gnome/include/atk-1.0
+        /usr/include/atk-1.0
+        /opt/include/atk-1.0
+        /sw/include/atk-1.0
+    )
+    gtk2_debug_message("GTK2_ATK_INCLUDE_DIR is ${GTK2_ATK_INCLUDE_DIR}")
+
+    find_library(GTK2_GTK_LIBRARY
+      NAMES
+        gtk-x11-2.0
+      PATHS
+        ${_GTK2LinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_GTK_LIBRARY is ${GTK2_GTK_LIBRARY}")
+
+    find_library(GTK2_GDK_LIBRARY
+      NAMES
+        gdk-x11-2.0
+      PATHS
+        ${_GDK2LinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_GDK_LIBRARY is ${GTK2_GDK_LIBRARY}")
+
+    find_library(GTK2_GDK_PIXBUF_LIBRARY
+      NAMES
+        gdk_pixbuf-2.0
+      PATHS
+        ${_GDK2LinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_GDK_PIXBUF_LIBRARY is ${GTK2_GDK_PIXBUF_LIBRARY}")
+
+    find_library(GTK2_GMODULE_LIBRARY
+      NAMES
+        gmodule-2.0
+      PATHS
+        ${_GMODULE2LinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_GMODULE_LIBRARY is ${GTK2_GMODULE_LIBRARY}")
+
+    find_library(GTK2_GTHREAD_LIBRARY
+      NAMES
+        gthread-2.0
+      PATHS
+        ${_GTK2LinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_GTHREAD_LIBRARY is ${GTK2_GTHREAD_LIBRARY}")
+
+    find_library(GTK2_GOBJECT_LIBRARY
+      NAMES
+        gobject-2.0
+      PATHS
+        ${_GTK2LinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_GOBJECT_LIBRARY is ${GTK2_GOBJECT_LIBRARY}")
+
+    find_library(GTK2_GLIB_LIBRARY
+      NAMES
+        glib-2.0
+      PATHS
+        ${_GLIB2LinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_GLIB_LIBRARY is ${GTK2_GLIB_LIBRARY}")
+
+    find_library(GTK2_GTKGL_LIBRARY
+      NAMES
+        gtkgl
+      PATHS
+        ${_GTK2LinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_GTKGL_LIBRARY is ${GTK2_GTKGL_LIBRARY}")
+
+    find_library(GTK2_GLADE_LIBRARY
+      NAMES
+        glade-2.0
+      PATHS
+        ${_GLADELinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_GLADE_LIBRARY is ${GTK2_GLADE_LIBRARY}")
+
+    find_library(GTK2_PANGO_LIBRARY
+      NAMES
+        pango-1.0
+      PATHS
+        ${_PANGOLinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_PANGO_LIBRARY is ${GTK2_PANGO_LIBRARY}")
+
+    find_library(GTK2_CAIRO_LIBRARY
+      NAMES
+        pangocairo-1.0
+      PATHS
+        ${_CAIROLinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_PANGO_LIBRARY is ${GTK2_CAIRO_LIBRARY}")
+
+    find_library(GTK2_ATK_LIBRARY
+      NAMES
+        atk-1.0
+      PATHS
+        ${_ATKinkDir}
+        /usr/lib
+        /usr/local/lib
+        /usr/openwin/lib
+        /usr/X11R6/lib
+        /opt/gnome/lib
+        /opt/lib
+        /sw/lib
+    )
+    gtk2_debug_message("GTK2_ATK_LIBRARY is ${GTK2_ATK_LIBRARY}")
+
+    set(GTK2_INCLUDE_DIRS
+      ${GTK2_GTK_INCLUDE_DIR}
+      ${GTK2_GLIBCONFIG_INCLUDE_DIR}
+      ${GTK2_GLIB_INCLUDE_DIR}
+      ${GTK2_GDK_INCLUDE_DIR}
+      ${GTK2_GLADE_INCLUDE_DIR}
+      ${GTK2_PANGO_INCLUDE_DIR}
+      ${GTK2_CAIRO_INCLUDE_DIR}
+      ${GTK2_ATK_INCLUDE_DIR}
+    )
+
+    if (GTK2_GTK_LIBRARY AND GTK2_GTK_INCLUDE_DIR)
+      if (GTK2_GDK_LIBRARY AND GTK2_GDK_PIXBUF_LIBRARY AND GTK2_GDK_INCLUDE_DIR)
+        if (GTK2_GMODULE_LIBRARY)
+          if (GTK2_GTHREAD_LIBRARY)
+            if (GTK2_GOBJECT_LIBRARY)
+              if (GTK2_GLADE_LIBRARY AND GTK2_GLADE_INCLUDE_DIR)
+                if (GTK2_PANGO_LIBRARY AND GTK2_PANGO_INCLUDE_DIR)
+                  if (GTK2_CAIRO_LIBRARY AND GTK2_CAIRO_INCLUDE_DIR)
+                    if (GTK2_ATK_LIBRARY AND GTK2_ATK_INCLUDE_DIR)
+
+                      # set GTK2 libraries
+                      set (GTK2_LIBRARIES
+                        ${GTK2_GTK_LIBRARY}
+                        ${GTK2_GDK_LIBRARY}
+                        ${GTK2_GDK_PIXBUF_LIBRARY}
+                        ${GTK2_GMODULE_LIBRARY}
+                        ${GTK2_GTHREAD_LIBRARY}
+                        ${GTK2_GOBJECT_LIBRARY}
+                        ${GTK2_GLADE_LIBRARY}
+                        ${GTK2_PANGO_LIBRARY}
+                        ${GTK2_CAIRO_LIBRARY}
+                        ${GTK2_ATK_LIBRARY}
+                      )
+
+                      # check for gtkgl support
+                      if (GTK2_GTKGL_LIBRARY AND GTK2_GTKGL_INCLUDE_DIR)
+                        set(GTK2_GTKGL_FOUND TRUE)
+
+                        set(GTK2_INCLUDE_DIRS
+                          ${GTK2_INCLUDE_DIR}
+                          ${GTK2_GTKGL_INCLUDE_DIR}
+                        )
+
+                        set(GTK2_LIBRARIES
+                          ${GTK2_LIBRARIES}
+                          ${GTK2_GTKGL_LIBRARY}
+                        )
+                      endif (GTK2_GTKGL_LIBRARY AND GTK2_GTKGL_INCLUDE_DIR)
+
+                    else (GTK2_ATK_LIBRARY AND GTK2_ATK_INCLUDE_DIR)
+                      message(SEND_ERROR "Could not find ATK")
+                    endif (GTK2_ATK_LIBRARY AND GTK2_ATK_INCLUDE_DIR)
+                  else (GTK2_CAIRO_LIBRARY AND GTK2_CAIRO_INCLUDE_DIR)
+                    message(SEND_ERROR "Could not find CAIRO")
+                  endif (GTK2_CAIRO_LIBRARY AND GTK2_CAIRO_INCLUDE_DIR)
+                else (GTK2_PANGO_LIBRARY AND GTK2_PANGO_INCLUDE_DIR)
+                  message(SEND_ERROR "Could not find PANGO")
+                endif (GTK2_PANGO_LIBRARY AND GTK2_PANGO_INCLUDE_DIR)
+              else (GTK2_GLADE_LIBRARY AND GTK2_GLADE_INCLUDE_DIR)
+                message(SEND_ERROR "Could not find GLADE")
+              endif (GTK2_GLADE_LIBRARY AND GTK2_GLADE_INCLUDE_DIR)
+            else (GTK2_GOBJECT_LIBRARY)
+              message(SEND_ERROR "Could not find GOBJECT")
+            endif (GTK2_GOBJECT_LIBRARY)
+          else (GTK2_GTHREAD_LIBRARY)
+            message(SEND_ERROR "Could not find GTHREAD")
+          endif (GTK2_GTHREAD_LIBRARY)
+        else (GTK2_GMODULE_LIBRARY)
+          message(SEND_ERROR "Could not find GMODULE")
+        endif (GTK2_GMODULE_LIBRARY)
+      else (GTK2_GDK_LIBRARY AND GTK2_GDK_PIXBUF_LIBRARY AND GTK2_GDK_INCLUDE_DIR)
+        message(SEND_ERROR "Could not find GDK (GDK_PIXBUF)")
+      endif (GTK2_GDK_LIBRARY AND GTK2_GDK_PIXBUF_LIBRARY AND GTK2_GDK_INCLUDE_DIR)
+    else (GTK2_GTK_LIBRARY AND GTK2_GTK_INCLUDE_DIR)
+      message(SEND_ERROR "Could not find GTK2-X11")
+    endif (GTK2_GTK_LIBRARY AND GTK2_GTK_INCLUDE_DIR)
+
+
+    if (GTK2_INCLUDE_DIRS AND GTK2_LIBRARIES)
+       set(GTK2_FOUND TRUE)
+    endif (GTK2_INCLUDE_DIRS AND GTK2_LIBRARIES)
+
+    if (GTK2_FOUND)
+      if (NOT GTK2_FIND_QUIETLY)
+        message(STATUS "Found GTK2: ${GTK2_LIBRARIES}")
+      endif (NOT GTK2_FIND_QUIETLY)
+    else (GTK2_FOUND)
+      if (GTK2_FIND_REQUIRED)
+        message(FATAL_ERROR "Could not find GTK2")
+      endif (GTK2_FIND_REQUIRED)
+    endif (GTK2_FOUND)
+
+    # show the GTK2_INCLUDE_DIRS and GTK2_LIBRARIES variables only in the advanced view
+    mark_as_advanced(GTK2_INCLUDE_DIRS GTK2_LIBRARIES)
+
+  endif (UNIX)
+endif (GTK2_LIBRARIES AND GTK2_INCLUDE_DIRS)
+
diff --git a/cmake/modules/FindGnomeVfs2.cmake b/cmake/modules/FindGnomeVfs2.cmake
new file mode 100644
index 0000000..5e4f99b
--- /dev/null
+++ b/cmake/modules/FindGnomeVfs2.cmake
@@ -0,0 +1,118 @@
+# - Try to find gnomevfs2 
+# Find gnomevfs2 headers, libraries and the answer to all questions.
+#
+#  GNOMEVFS2_FOUND               True if gnomevfs2 got found
+#  GNOMEVFS2_INCLUDEDIR          Location of gnomevfs2 headers 
+#  GNOMEVFS2_LIBRARIES           List of libaries to use gnomevfs2
+#  GNOMEVFS2_DEFINITIONS         Definitions to compile gnomevfs2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about gnome-vfs-2.0.pc settings
+IF ( GnomeVfs2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( GnomeVfs2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( GnomeVfs2_FIND_REQUIRED )
+
+pkg_search_module( GNOMEVFS2 ${_pkgconfig_REQUIRED} gnome-vfs-2.0 )
+
+
+# Look for gnomevfs2 include dir and libraries w/o pkgconfig
+IF ( NOT GNOMEVFS2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _gnomevfs2_include_DIR libgnomevfs/gnome-vfs.h PATH_SUFFIXES gnome-vfs-2.0 
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+	)
+	FIND_PATH( _gnomevfs2_filesize_include_DIR gnome-vfs-file-size.h 
+		PATHS
+		/opt/gnome/lib64/gnome-vfs-2.0/include
+		/opt/gnome/lib/gnome-vfs-2.0/include
+		/opt/lib/gnome-vfs-2.0/include
+		/opt/local/lib/gnome-vfs-2.0/include
+		/sw/lib/gnome-vfs-2.0/include
+		/usr/lib64/gnome-vfs-2.0/include
+		/usr/lib/gnome-vfs-2.0/include
+	)
+	FIND_LIBRARY( _gnomevfs2_link_DIR gnomevfs-2
+		PATHS
+		/opt/local/lib
+		/sw/lib
+		/usr/lib
+		/usr/local/lib
+		/usr/lib64
+		/usr/local/lib64
+		/opt/lib64
+	)
+	IF ( _gnomevfs2_include_DIR AND _gnomevfs2_filesize_include_DIR AND _gnomevfs2_link_DIR )
+		SET ( _gnomevfs2_FOUND TRUE )
+	ENDIF ( _gnomevfs2_include_DIR AND _gnomevfs2_filesize_include_DIR AND _gnomevfs2_link_DIR )
+
+
+	IF ( _gnomevfs2_FOUND )
+		SET ( GNOMEVFS2_INCLUDE_DIRS ${_gnomevfs2_include_DIR} ${_gnomevfs2_filesize_include_DIR} )
+		SET ( GNOMEVFS2_LIBRARIES ${_gnomevfs2_link_DIR} )
+	ENDIF ( _gnomevfs2_FOUND )
+
+	# Handle dependencies
+	IF ( NOT GCONF2_FOUND )
+		FIND_PACKAGE( GConf2 REQUIRED)
+		IF ( GCONF2_FOUND )
+			SET ( GNOMEVFS2_INCLUDE_DIRS ${GNOMEVFS2_INCLUDE_DIRS} ${GCONF2_INCLUDE_DIRS} )
+			SET ( GNOMEVFS2_LIBRARIES ${GNOMEVFS2_LIBRARIES} ${GCONF2_LIBRARIES} )
+		ENDIF ( GCONF2_FOUND )
+	ENDIF ( NOT GCONF2_FOUND )
+        IF ( NOT GLIB2_FOUND )
+                FIND_PACKAGE( GLIB2 REQUIRED)
+
+                IF ( GTHREAD2_FOUND )
+                        SET ( GNOMEVFS2_INCLUDE_DIRS ${GNOMEVFS2_INCLUDE_DIRS} ${GTHREAD2_INCLUDE_DIR} )
+                        SET ( GNOMEVFS2_LIBRARIES ${GNOMEVFS2_LIBRARIES} ${GTHREAD2_LIBRARY} )
+                ENDIF ( GTHREAD2_FOUND )
+                IF ( GMODULE2_FOUND )
+                        SET ( GNOMEVFS2_INCLUDE_DIRS ${GNOMEVFS2_INCLUDE_DIRS} ${GMODULE2_INCLUDE_DIR} )
+                        SET ( GNOMEVFS2_LIBRARIES ${GNOMEVFS2_LIBRARIES} ${GMODULE2_LIBRARY} )
+                ENDIF ( GMODULE2_FOUND )
+                IF ( GOBJECT2_FOUND )
+                        SET ( GNOMEVFS2_INCLUDE_DIRS ${GNOMEVFS2_INCLUDE_DIRS} ${GOBJECT2_INCLUDE_DIR} )
+                        SET ( GNOMEVFS2_LIBRARIES ${GNOMEVFS2_LIBRARIES} ${GOBJECT2_LIBRARY} )
+                ENDIF ( GOBJECT2_FOUND )
+                IF ( GLIB2_FOUND )
+                        SET ( GNOMEVFS2_INCLUDE_DIRS ${GNOMEVFS2_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIR} ${GLIBCONFIG_INCLUDE_DIR} )
+                        SET ( GNOMEVFS2_LIBRARIES ${GNOMEVFS2_LIBRARIES} ${GLIB2_LIBRARY} )
+                ENDIF ( GLIB2_FOUND )
+        ENDIF ( NOT GLIB2_FOUND )
+
+
+	# Report results
+	IF ( GNOMEVFS2_LIBRARIES AND GNOMEVFS2_INCLUDE_DIRS AND _gnomevfs2_FOUND )	
+		SET( GNOMEVFS2_FOUND 1 )
+		IF ( NOT GnomeVfs2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found gnomevfs2: ${GNOMEVFS2_LIBRARIES} ${GNOMEVFS2_INCLUDE_DIRS}" )
+		ENDIF ( NOT GnomeVfs2_FIND_QUIETLY )
+	ELSE ( GNOMEVFS2_LIBRARIES AND GNOMEVFS2_INCLUDE_DIRS AND _gnomevfs2_FOUND )	
+		IF ( GnomeVfs2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find gnomevfs2" )
+		ELSE ( GnomeVfs2_FIND_REQUIRED )
+			IF ( NOT GnomeVfs2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find gnomevfs2" )	
+			ENDIF ( NOT GnomeVfs2_FIND_QUIETLY )
+		ENDIF ( GnomeVfs2_FIND_REQUIRED )
+	ENDIF ( GNOMEVFS2_LIBRARIES AND GNOMEVFS2_INCLUDE_DIRS AND _gnomevfs2_FOUND )	
+
+ENDIF ( NOT GNOMEVFS2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( GNOMEVFS2_LIBRARIES GNOMEVFS2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindIconv.cmake b/cmake/modules/FindIconv.cmake
new file mode 100644
index 0000000..db141d4
--- /dev/null
+++ b/cmake/modules/FindIconv.cmake
@@ -0,0 +1,58 @@
+
+# This original file is from eiskaltdc at http://code.google.com/p/eiskaltdc/.
+# The file itself does not contain a copyright notice
+# but the whole project is released under GPL v3 (or any later version).
+# Timestamp: 20101-Jan-05
+#
+#  Copyright (c) 2010 Michael Bell 
+
+if (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+  # Already in cache, be silent
+  set(ICONV_FIND_QUIETLY TRUE)
+endif (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+
+find_path(ICONV_INCLUDE_DIR iconv.h)
+
+find_library(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c)
+
+if (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+   set (ICONV_FOUND TRUE)
+endif (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+
+set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES})
+
+if (ICONV_FOUND)
+  include(CheckCSourceCompiles)
+  CHECK_C_SOURCE_COMPILES("
+  #include 
+  int main(){
+    iconv_t conv = 0;
+    const char* in = 0;
+    size_t ilen = 0;
+    char* out = 0;
+    size_t olen = 0;
+    iconv(conv, &in, &ilen, &out, &olen);
+    return 0;
+  }
+" ICONV_SECOND_ARGUMENT_IS_CONST )
+endif (ICONV_FOUND)
+
+set (CMAKE_REQUIRED_INCLUDES)
+set (CMAKE_REQUIRED_LIBRARIES)
+
+if (ICONV_FOUND)
+  if (NOT ICONV_FIND_QUIETLY)
+    message (STATUS "Found Iconv: ${ICONV_LIBRARIES}")
+  endif (NOT ICONV_FIND_QUIETLY)
+else (ICONV_FOUND)
+  if (Iconv_FIND_REQUIRED)
+    message (FATAL_ERROR "Could not find Iconv")
+  endif (Iconv_FIND_REQUIRED)
+endif (ICONV_FOUND)
+
+MARK_AS_ADVANCED(
+  ICONV_INCLUDE_DIR
+  ICONV_LIBRARIES
+  ICONV_SECOND_ARGUMENT_IS_CONST
+)
diff --git a/cmake/modules/FindKDEPIM3.cmake b/cmake/modules/FindKDEPIM3.cmake
new file mode 100644
index 0000000..fdbfd16
--- /dev/null
+++ b/cmake/modules/FindKDEPIM3.cmake
@@ -0,0 +1,41 @@
+# - Try to find KDEPIM3
+# Find KDEPIM3 headers, libraries and the answer to all questions.
+#
+#  KDEPIM3_FOUND               True if KDEPIM3 got found
+#  KDEPIM3_INCLUDE_DIR         Location of KDEPIM3 headers 
+#  KDEPIM3_KCAL_LIBRARIES      List of libaries to use KABC of KDEPIM3 
+#  KDEPIM3_KABC_LIBRARIES      List of libaries to use KCAL of KDEPIM3 
+#  KDEPIM3_DEFINITIONS         Definitions to compile KDEPIM3 
+#
+# Copyright (c) 2007 Daniel Gollub 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+FIND_PACKAGE( KDE3 REQUIRED )
+
+FIND_PATH( KDEPIM3_INCLUDE_DIR kdepimmacros.h ${KDE3_INCLUDE_DIR} )
+FIND_LIBRARY( KDEPIM3_KCAL_LIBRARIES kcal ${KDE3_LIB_DIR} )
+FIND_LIBRARY( KDEPIM3_KABC_LIBRARIES kabc ${KDE3_LIB_DIR} )
+
+# Report results
+IF ( KDEPIM3_KCAL_LIBRARIES AND KDEPIM3_KABC_LIBRARIES AND KDEPIM3_INCLUDE_DIR )
+	SET( KDEPIM3_FOUND 1 )
+	IF ( NOT KDEPIM3_FIND_QUIETLY )
+		MESSAGE( STATUS "Found KDE PIM 3: ${KDEPIM3_KABC_LIBRARIES} ${KDEPIM3_KCAL_LIBRARIES}" )
+	ENDIF ( NOT KDEPIM3_FIND_QUIETLY )
+ELSE ( KDEPIM3_KCAL_LIBRARIES AND KDEPIM3_KABC_LIBRARIES AND KDEPIM3_INCLUDE_DIR )
+	IF ( KDEPIM3_FIND_REQUIRED )
+		MESSAGE( SEND_ERROR "Could NOT find KDE PIM 3" )
+	ELSE ( KDEPIM3_FIND_REQUIRED )
+		IF ( NOT KDEPIM3_FIND_QUIETLY )
+			MESSAGE( STATUS "Could NOT find KDE PIM 3" )
+		ENDIF ( NOT KDEPIM3_FIND_QUIETLY )
+	ENDIF ( KDEPIM3_FIND_REQUIRED )
+ENDIF ( KDEPIM3_KCAL_LIBRARIES AND KDEPIM3_KABC_LIBRARIES AND KDEPIM3_INCLUDE_DIR )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( KDEPIM3_KCAL_LIBRARIES KDEPIM3_KABC_LIBRARIES KDEPIM3_INCLUDE_DIR )
+
diff --git a/cmake/modules/FindLibDbus.cmake b/cmake/modules/FindLibDbus.cmake
new file mode 100644
index 0000000..1e66ce7
--- /dev/null
+++ b/cmake/modules/FindLibDbus.cmake
@@ -0,0 +1,51 @@
+# - Try to find LIBDBUS 
+# Find LIBDBUS headers, libraries and the answer to all questions.
+#
+#  LIBDBUS_FOUND               True if libdbus got found
+#  LIBDBUS_INCLUDE_DIRS        Location of libdbus headers 
+#  LIBDBUS_LIBRARIES           List of libraries to use libdbus 
+#
+# Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( LibDbus_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( LibDbus_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( LibDbus_FIND_REQUIRED )
+
+IF ( LIBDBUS_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBDBUS ${_pkgconfig_REQUIRED} dbus-1>=${LIBDBUS_MIN_VERSION} )
+ELSE ( LIBDBUS_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBDBUS ${_pkgconfig_REQUIRED} dbus-1 )
+ENDIF ( LIBDBUS_MIN_VERSION )
+
+
+IF( NOT LIBDBUS_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( LIBDBUS_INCLUDE_DIRS dbus/dbus.h PATH_SUFFIXES dbus-1.0 dbus )
+	FIND_LIBRARY( LIBDBUS_LIBRARIES dbus dbus-1)
+
+	# Report results
+	IF ( LIBDBUS_LIBRARIES AND LIBDBUS_INCLUDE_DIRS )	
+		SET( LIBDBUS_FOUND 1 )
+		IF ( NOT LIBDBUS_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libdbus: ${LIBDBUS_LIBRARIES}" )
+		ENDIF ( NOT LIBDBUS_FIND_QUIETLY )
+	ELSE ( LIBDBUS_LIBRARIES AND LIBDBUS_INCLUDE_DIRS )	
+		IF ( LIBDBUS_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libdbus" )
+		ELSE ( LIBDBUS_FIND_REQUIRED )
+			IF ( NOT LIBDBUS_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libdbus" )	
+			ENDIF ( NOT LIBDBUS_FIND_QUIETLY )
+		ENDIF ( LIBDBUS_FIND_REQUIRED )
+	ENDIF ( LIBDBUS_LIBRARIES AND LIBDBUS_INCLUDE_DIRS )
+ENDIF( NOT LIBDBUS_FOUND AND NOT PKG_CONFIG_FOUND )
+
+MARK_AS_ADVANCED( LIBDBUS_LIBRARIES LIBDBUS_INCLUDE_DIRS )
\ No newline at end of file
diff --git a/cmake/modules/FindLibDbusGlib.cmake b/cmake/modules/FindLibDbusGlib.cmake
new file mode 100644
index 0000000..6f366dc
--- /dev/null
+++ b/cmake/modules/FindLibDbusGlib.cmake
@@ -0,0 +1,51 @@
+# - Try to find LIBDBUS GLIB Bindings
+# Find LIBDBUSGLIB headers, libraries and the answer to all questions.
+#
+#  LIBDBUSGLIB_FOUND               True if libdbus-glib got found
+#  LIBDBUSGLIB_INCLUDE_DIRS        Location of libdbus-glib headers 
+#  LIBDBUSGLIB_LIBRARIES           List of libraries to use libdbus-glib 
+#
+# Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( LibDbusGlib_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( LibDbusGlib_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( LibDbusGlib_FIND_REQUIRED )
+
+IF ( LIBDBUSGLIB_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBDBUSGLIB ${_pkgconfig_REQUIRED} dbus-glib-1>=${LIBDBUSGLIB_MIN_VERSION} )
+ELSE ( LIBDBUSGLIB_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBDBUSGLIB ${_pkgconfig_REQUIRED} dbus-glib-1 )
+ENDIF ( LIBDBUSGLIB_MIN_VERSION )
+
+
+IF( NOT LIBDBUSGLIB_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( LIBDBUSGLIB_INCLUDE_DIRS dbus/dbus-glib.h PATH_SUFFIXES dbus-1.0 dbus )
+	FIND_LIBRARY( LIBDBUSGLIB_LIBRARIES dbus-glib dbus-glib-1)
+
+	# Report results
+	IF ( LIBDBUSGLIB_LIBRARIES AND LIBDBUSGLIB_INCLUDE_DIRS )	
+		SET( LIBDBUSGLIB_FOUND 1 )
+		IF ( NOT LIBDBUSGLIB_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libdbus-glib: ${LIBDBUSGLIB_LIBRARIES}" )
+		ENDIF ( NOT LIBDBUSGLIB_FIND_QUIETLY )
+	ELSE ( LIBDBUSGLIB_LIBRARIES AND LIBDBUSGLIB_INCLUDE_DIRS )	
+		IF ( LIBDBUSGLIB_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libdbus-glib" )
+		ELSE ( LIBDBUSGLIB_FIND_REQUIRED )
+			IF ( NOT LIBDBUSGLIB_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libdbus-glib" )	
+			ENDIF ( NOT LIBDBUSGLIB_FIND_QUIETLY )
+		ENDIF ( LIBDBUSGLIB_FIND_REQUIRED )
+	ENDIF ( LIBDBUSGLIB_LIBRARIES AND LIBDBUSGLIB_INCLUDE_DIRS )
+ENDIF( NOT LIBDBUSGLIB_FOUND AND NOT PKG_CONFIG_FOUND )
+
+MARK_AS_ADVANCED( LIBDBUSGLIB_LIBRARIES LIBDBUSGLIB_INCLUDE_DIRS )
\ No newline at end of file
diff --git a/cmake/modules/FindLibExslt.cmake b/cmake/modules/FindLibExslt.cmake
new file mode 100644
index 0000000..11d5214
--- /dev/null
+++ b/cmake/modules/FindLibExslt.cmake
@@ -0,0 +1,82 @@
+# - Try to find libexslt
+# Find libexslt headers, libraries and the answer to all questions.
+#
+#  LIBEXSLT_FOUND               True if libexslt got found
+#  LIBEXSLT_INCLUDE_DIRS         Location of libexslt headers 
+#  LIBEXSLT_LIBRARIES           List of libaries to use libexslt
+#
+#  Copyright (c) 2008 Daniel Gollub 
+#  Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+# Take care about libexslt.pc settings
+IF ( LibExslt_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( LibExslt_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( LibExslt_FIND_REQUIRED )
+
+IF ( LIBEXSLT_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBEXSLT ${_pkgconfig_REQUIRED} libexslt >= ${LIBEXSLT_MIN_VERSION} )
+ELSE( LIBEXSLT_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBEXSLT ${_pkgconfig_REQUIRED} libexslt )
+ENDIF ( LIBEXSLT_MIN_VERSION )
+
+
+# Look for libexslt include dir and libraries without pkg-config...
+IF ( NOT LIBEXSLT_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libexslt_include_DIR libexslt/exslt.h 
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+
+	FIND_LIBRARY( _libexslt_link_DIR NAMES exslt libexslt
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+	IF ( _libexslt_include_DIR AND _libexslt_link_DIR )
+		SET ( _libexslt_FOUND TRUE )
+	ENDIF ( _libexslt_include_DIR AND _libexslt_link_DIR )
+
+	IF ( _libexslt_FOUND )
+		SET ( LIBEXSLT_INCLUDE_DIRS ${_libexslt_include_DIR} )
+		SET ( LIBEXSLT_LIBRARIES ${_libexslt_link_DIR} )
+	ENDIF ( _libexslt_FOUND )
+
+	# Report results
+	IF ( LIBEXSLT_LIBRARIES AND LIBEXSLT_INCLUDE_DIRS )	
+		SET( LIBEXSLT_FOUND 1 )
+		IF ( NOT LibExslt_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libexslt: ${LIBEXSLT_LIBRARIES} ${LIBEXSLT_INCLUDE_DIRS}" )
+		ENDIF ( NOT LibExslt_FIND_QUIETLY )
+	ELSE ( LIBEXSLT_LIBRARIES AND LIBEXSLT_INCLUDE_DIRS )	
+		IF ( LibExslt_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libexslt" )
+		ELSE ( LibExslt_FIND_REQUIRED )
+			IF ( NOT LibExslt_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libexslt" )	
+			ENDIF ( NOT LibExslt_FIND_QUIETLY )
+		ENDIF ( LibExslt_FIND_REQUIRED )
+	ENDIF ( LIBEXSLT_LIBRARIES AND LIBEXSLT_INCLUDE_DIRS )	
+
+ENDIF ( NOT LIBEXSLT_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBEXSLT_LIBRARIES LIBEXSLT_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindLibGCrypt.cmake b/cmake/modules/FindLibGCrypt.cmake
new file mode 100644
index 0000000..05284a0
--- /dev/null
+++ b/cmake/modules/FindLibGCrypt.cmake
@@ -0,0 +1,37 @@
+# Try and find libgcrypt.
+# As soon as libgcrypt has been found, the following variables will be defined:
+#
+# LIBGCRYPT_FOUND
+# GCRYPT_INCLUDE_DIR
+# GCRYPT_LIBRARY:FILEPATH
+#
+# Copyright (c) 2009 Juergen Leising 
+#
+# Redistribution and use is allowed according to the terms of the New
+# BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+MESSAGE(STATUS "checking for libgcrypt...")
+
+FIND_PATH(GCRYPT_INCLUDE_DIR NAMES gcrypt.h 
+                             PATHS /include /usr/include /usr/local/include /usr/share/include /opt/include 
+                             DOC "Try and find the header file gcrypt.h")
+
+FIND_LIBRARY(GCRYPT_LIBRARY NAMES gcrypt
+                            PATHS /usr/lib /lib /usr/local/lib /usr/share/lib /opt/lib /opt/share/lib /var/lib /usr/lib64 /lib64 /usr/local/lib64 /usr/share/lib64 /opt/lib64 /opt/share/lib64 /var/lib64
+                            DOC "Try and find libgcrypt")
+
+IF (GCRYPT_INCLUDE_DIR AND GCRYPT_LIBRARY)
+	SET (LIBGCRYPT_FOUND 1)
+  get_filename_component(GCRYPT_LIBRARY_DIRS ${GCRYPT_LIBRARY} PATH)
+  MESSAGE(STATUS "  Found ${GCRYPT_LIBRARY}")
+ELSE (GCRYPT_INCLUDE_DIR AND GCRYPT_LIBRARY)
+	IF ( LibGCrypt_FIND_REQUIRED )
+	  MESSAGE( FATAL_ERROR "  Could NOT find libgcrypt. The ldap plugin needs this library." )
+	ELSE ( LibGCrypt_FIND_REQUIRED )
+		MESSAGE ( STATUS "  Could NOT find libgcrypt.")
+	ENDIF ( LibGCrypt_FIND_REQUIRED )
+ENDIF (GCRYPT_INCLUDE_DIR AND GCRYPT_LIBRARY)
+
+
diff --git a/cmake/modules/FindLibGSSAPIV2.cmake b/cmake/modules/FindLibGSSAPIV2.cmake
new file mode 100644
index 0000000..a2f874f
--- /dev/null
+++ b/cmake/modules/FindLibGSSAPIV2.cmake
@@ -0,0 +1,34 @@
+# Try and find libgssapiv2.
+# As soon as libgssapiv2 has been found, the following variables will be defined:
+#
+# LIBGSSAPIV2_FOUND
+# GSSAPIV2_LIBRARY:FILEPATH
+#
+# Copyright (c) 2009 Juergen Leising 
+#
+# Redistribution and use is allowed according to the terms of the New
+# BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+MESSAGE(STATUS "checking for libgssapiv2...")
+
+# No header files required for the ldap plugin.
+
+FIND_LIBRARY(GSSAPIV2_LIBRARY NAMES gssapiv2 
+                              PATHS /usr/lib /lib /usr/local/lib /usr/share/lib /opt/lib /opt/share/lib /var/lib /usr/lib/sasl2 /lib/sasl2 /usr/local/lib/sasl2 /usr/share/lib/sasl2 /opt/lib/sasl2 /opt/share/lib/sasl2 /var/lib/sasl2 /usr/lib64 /lib64 /usr/local/lib64 /usr/share/lib64 /opt/lib64 /opt/share/lib64 /var/lib64 /usr/lib64/sasl2 /lib64/sasl2 /usr/local/lib64/sasl2 /usr/share/lib64/sasl2 /opt/lib64/sasl2 /opt/share/lib64/sasl2 /var/lib64/sasl2
+                              DOC "Try and find libgssapiv2")
+
+IF (GSSAPIV2_LIBRARY)
+	SET (LIBGSSAPIV2_FOUND 1)
+  get_filename_component(GSSAPIV2_LIBRARY_DIRS ${GSSAPIV2_LIBRARY} PATH)
+  MESSAGE(STATUS "  Found ${GSSAPIV2_LIBRARY}")
+ELSE (GSSAPIV2_LIBRARY)
+	IF ( LibGSSAPIV2_FIND_REQUIRED )	
+		MESSAGE( FATAL_ERROR "  Could NOT find libgssapiv2. The ldap plugin needs this library.")
+	ELSE ( LibGSSAPIV2_FIND_REQUIRED )
+	  MESSAGE( STATUS "  Could NOT find libgssapiv2. The SASL authentication mechanism GSSAPI (and KERBEROS V5) won't work, therefore. Not a fatal error, however. The ldap plugin itself does NOT need it.")
+	ENDIF ( LibGSSAPIV2_FIND_REQUIRED )
+ENDIF (GSSAPIV2_LIBRARY)
+
diff --git a/cmake/modules/FindLibGcal.cmake b/cmake/modules/FindLibGcal.cmake
new file mode 100644
index 0000000..730a7e3
--- /dev/null
+++ b/cmake/modules/FindLibGcal.cmake
@@ -0,0 +1,83 @@
+# - Try to find libgcal
+# Find libgcal headers, libraries and the answer to all questions.
+#
+#  LIBGCAL_FOUND               True if libgcal got found
+#  LIBGCAL_INCLUDE_DIRS         Location of libgcal headers
+#  LIBGCAL_LIBRARIES           List of libaries to use libgcal
+#  LIBGCAL_DEFINITIONS         Definitions to compile libgcal
+#
+# Copyright (c) 2006, Alexander Neundorf, 
+# Copyright (c) 2007 Alban Browaeys 
+# Copyright (c) 2008 Adenilson Cavalcanti 
+#  Adapted this to scan for libgcal
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libgcal.pc settings
+IF ( Libgcal_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( Libgcal_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( Libgcal_FIND_REQUIRED )
+
+IF ( LIBGCAL_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBGCAL ${_pkgconfig_REQUIRED} libgcal>=${LIBGCAL_MIN_VERSION} )
+ELSE ( LIBGCAL_MIN_VERSION )
+	pkg_search_module( LIBGCAL ${_pkgconfig_REQUIRED} libgcal )
+ENDIF ( LIBGCAL_MIN_VERSION )
+
+
+# Look for libgcal include dir and libraries w/o pkgconfig
+IF ( NOT LIBGCAL_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libgcal_include_DIR gcal.h
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+	)
+	FIND_LIBRARY( _libgcal_link_DIR NAME libgcal
+		PATHS
+		/opt/local/lib
+		/sw/lib
+		/usr/lib
+		/usr/local/lib
+		/usr/lib64
+		/usr/local/lib64
+		/opt/lib64
+	)
+	IF ( _libgcal_include_DIR AND _libgcal_link_DIR )
+		SET ( _libgcal_FOUND TRUE )
+	ENDIF ( _libgcal_include_DIR AND _libgcal_link_DIR )
+
+
+	IF ( _libgcal_FOUND )
+		SET ( LIBGCAL_INCLUDE_DIRS ${_libgcal_include_DIR} )
+		SET ( LIBGCAL_LIBRARIES ${_libgcal_link_DIR} )
+	ENDIF ( _libgcal_FOUND )
+
+	# Report results
+	IF ( LIBGCAL_LIBRARIES AND LIBGCAL_INCLUDE_DIRS AND _libgcal_FOUND )
+		SET( LIBGCAL_FOUND 1 )
+		IF ( NOT Libgcal_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libgcal: ${LIBGCAL_LIBRARIES} ${LIBGCAL_INCLUDE_DIRS}" )
+		ENDIF ( NOT Libgcal_FIND_QUIETLY )
+	ELSE ( LIBGCAL_LIBRARIES AND LIBGCAL_INCLUDE_DIRS AND _libgcal_FOUND )
+		IF ( Libgcal_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libgcal" )
+		ELSE ( Libgcal_FIND_REQUIRED )
+			IF ( NOT Libgcal_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libgcal" )
+			ENDIF ( NOT Libgcal_FIND_QUIETLY )
+		ENDIF ( Libgcal_FIND_REQUIRED )
+	ENDIF ( LIBGCAL_LIBRARIES AND LIBGCAL_INCLUDE_DIRS AND _libgcal_FOUND )
+
+ENDIF ( NOT LIBGCAL_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBGCAL_LIBRARIES LIBGCAL_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindLibGlade.cmake b/cmake/modules/FindLibGlade.cmake
new file mode 100644
index 0000000..10fffc8
--- /dev/null
+++ b/cmake/modules/FindLibGlade.cmake
@@ -0,0 +1,55 @@
+# - Try to find LIBGLADE
+# Find LIBGLADE headers, libraries and the answer to all questions.
+#
+#  LIBGLADE_FOUND               True if LIBGLADE got found
+#  LIBGLADE_INCLUDE_DIR         Location of LIBGLADE headers 
+#  LIBGLADE_LIBRARIES           List of libaries to use LIBGLADE
+#  LIBGLADE_DEFINITIONS         Definitions to compile LIBGLADE 
+#
+#  Copyright (c) 2007 Daniel Gollub 
+#  Copyright (c) 2008 Daniel Friedrich 
+#  Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( LibGlade_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( LibGlade_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( LibGlade_FIND_REQUIRED )
+
+IF ( LIBGLADE_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBGLADE ${_pkgconfig_REQUIRED} libglade-2.0>=${LIBGLADE_MIN_VERSION} )
+ELSE ( LIBGLADE_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBGLADE ${_pkgconfig_REQUIRED} libglade-2.0 )
+ENDIF ( LIBGLADE_MIN_VERSION )
+
+
+IF( NOT LIBGLADE_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH(LIBGLADE_INCLUDE_DIRS glade/glade.h )
+	FIND_LIBRARY( LIBGLADE_LIBRARIES glade-2.0)
+
+	# Report results
+	IF ( LIBGLADE_LIBRARIES AND LIBGLADE_INCLUDE_DIRS )	
+		SET( LIBGLADE_FOUND 1 )
+		IF ( NOT LIBGLADE_FIND_QUIETLY )
+			MESSAGE( STATUS "Found LIBGLADE: ${LIBGLADE_LIBRARIES}" )
+		ENDIF ( NOT LIBGLADE_FIND_QUIETLY )
+	ELSE ( LIBGLADE_LIBRARIES AND LIBGLADE_INCLUDE_DIRS )	
+		IF ( LibGlade_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find LIBGLADE" )
+		ELSE ( LibGlade_FIND_REQUIRED )
+			IF ( NOT LIBGLADE_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find LIBGLADE" )	
+			ENDIF ( NOT LIBGLADE_FIND_QUIETLY )
+		ENDIF ( LibGlade_FIND_REQUIRED )
+	ENDIF ( LIBGLADE_LIBRARIES AND LIBGLADE_INCLUDE_DIRS )
+ENDIF( NOT LIBGLADE_FOUND AND NOT PKG_CONFIG_FOUND )	
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBGLADE_LIBRARIES LIBGLADE_INCLUDE_DIRS )
diff --git a/cmake/modules/FindLibGnome2.cmake b/cmake/modules/FindLibGnome2.cmake
new file mode 100644
index 0000000..338f2e9
--- /dev/null
+++ b/cmake/modules/FindLibGnome2.cmake
@@ -0,0 +1,112 @@
+# - Try to find libgnome2 
+# Find libgnome2 headers, libraries and the answer to all questions.
+#
+#  LIBGNOME2_FOUND               True if libgnome2 got found
+#  LIBGNOME2_INCLUDEDIR          Location of libgnome2 headers 
+#  LIBGNOME2_LIBRARIES           List of libaries to use libgnome2
+#  LIBGNOME2_DEFINITIONS         Definitions to compile libgnome2 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+
+
+
+
+
+
+INCLUDE( FindPkgConfig )
+# Take care about libgnome-2.0.pc settings
+IF ( LibGnome2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( LibGnome2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( LibGnome2_FIND_REQUIRED )
+
+IF ( LIBGNOME2_MIN_VERSION )
+	pkg_search_module( LIBGNOME2 ${_pkgconfig_REQUIRED} libgnome-2.0>=${LIBGNOME2_MIN_VERSION} )
+ELSE ( LIBGNOME2_MIN_VERSION )
+	pkg_search_module( LIBGNOME2 ${_pkgconfig_REQUIRED} libgnome-2.0 )
+ENDIF ( LIBGNOME2_MIN_VERSION )
+
+
+# Look for libgnome2 include dir and libraries w/o pkgconfig
+IF ( NOT LIBGNOME2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libgnome2_include_DIR libgnome/libgnome.h PATH_SUFFIXES libgnome-2.0 
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+	)
+	FIND_LIBRARY( _libgnome2_link_DIR gnome-2 
+		PATHS
+		/opt/local/lib
+		/sw/lib
+		/usr/lib
+		/usr/local/lib
+		/usr/lib64
+		/usr/local/lib64
+		/opt/lib64
+	)
+	IF ( _libgnome2_include_DIR AND _libgnome2_link_DIR )
+		SET ( _libgnome2_FOUND TRUE )
+	ENDIF ( _libgnome2_include_DIR AND _libgnome2_link_DIR )
+
+
+	IF ( _libgnome2_FOUND )
+		SET ( LIBGNOME2_INCLUDE_DIRS ${_libgnome2_include_DIR} )
+		SET ( LIBGNOME2_LIBRARIES ${_libgnome2_link_DIR} )
+	ENDIF ( _libgnome2_FOUND )
+
+	# Handle dependencies
+	IF ( NOT BONOBO2_FOUND )
+		FIND_PACKAGE( BONOBO2 REQUIRED)
+		IF ( BONOBO2_FOUND )
+			SET ( LIBGNOME2_INCLUDE_DIRS ${LIBGNOME2_INCLUDE_DIRS} ${BONOBO2_INCLUDE_DIRS} )
+			SET ( LIBGNOME2_LIBRARIES ${LIBGNOME2_LIBRARIES} ${BONOBO2_LIBRARIES} )
+		ENDIF ( BONOBO2_FOUND )
+	ENDIF ( NOT BONOBO2_FOUND )
+        IF ( NOT GLIB2_FOUND )
+                FIND_PACKAGE( GLIB2 REQUIRED)
+
+                IF ( GMODULE2_FOUND )
+                        SET ( LIBGNOME2_INCLUDE_DIRS ${LIBGNOME2_INCLUDE_DIRS} ${GMODULE2_INCLUDE_DIR} )
+                        SET ( LIBGNOME2_LIBRARIES ${LIBGNOME2_LIBRARIES} ${GMODULE2_LIBRARY} )
+                ENDIF ( GMODULE2_FOUND )
+                IF ( GLIB2_FOUND )
+                        SET ( LIBGNOME2_INCLUDE_DIRS ${LIBGNOME2_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIR} ${GLIBCONFIG_INCLUDE_DIR} )
+                        SET ( LIBGNOME2_LIBRARIES ${LIBGNOME2_LIBRARIES} ${GLIB2_LIBRARY} )
+                ENDIF ( GLIB2_FOUND )
+        ENDIF ( NOT GLIB2_FOUND )
+
+
+
+	# Report results
+	IF ( LIBGNOME2_LIBRARIES AND LIBGNOME2_INCLUDE_DIRS AND _libgnome2_FOUND )	
+		SET( LIBGNOME2_FOUND 1 )
+		IF ( NOT LibGnome2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libgnome2: ${LIBGNOME2_LIBRARIES} ${LIBGNOME2_INCLUDE_DIRS}" )
+		ENDIF ( NOT LibGnome2_FIND_QUIETLY )
+	ELSE ( LIBGNOME2_LIBRARIES AND LIBGNOME2_INCLUDE_DIRS AND _libgnome2_FOUND )	
+		IF ( LibGnome2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libgnome2" )
+		ELSE ( LibGnome2_FIND_REQUIRED )
+			IF ( NOT LibGnome2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libgnome2" )	
+			ENDIF ( NOT LibGnome2_FIND_QUIETLY )
+		ENDIF ( LibGnome2_FIND_REQUIRED )
+	ENDIF ( LIBGNOME2_LIBRARIES AND LIBGNOME2_INCLUDE_DIRS AND _libgnome2_FOUND )	
+
+ENDIF ( NOT LIBGNOME2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBGNOME2_LIBRARIES LIBGNOME2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindLibLdap.cmake b/cmake/modules/FindLibLdap.cmake
new file mode 100644
index 0000000..6ef7874
--- /dev/null
+++ b/cmake/modules/FindLibLdap.cmake
@@ -0,0 +1,69 @@
+# Try and find libldap.
+# As soon as libldap has been found, the following variables will be defined:
+#
+# LIBLDAP_FOUND
+# LDAP_INCLUDE_DIR
+# LDAP_LIBRARY:FILEPATH
+#
+#
+# Copyright (c) 2009 Juergen Leising 
+#
+# Redistribution and use is allowed according to the terms of the New
+# BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+MESSAGE(STATUS "checking for libldap and liblber...")
+
+FIND_PATH(LDAP_INCLUDE_DIR NAMES ldap.h 
+                           PATHS /include /usr/include /usr/local/include /usr/share/include /opt/include 
+                           DOC "Try and find the header file ldap.h")
+
+FIND_PATH(LBER_INCLUDE_DIR NAMES lber.h
+                           PATHS /include /usr/include /usr/local/include /usr/share/include /opt/include ${LDAP_INCLUDE_DIR} 
+                           DOC "Try and find the header file lber.h")
+
+
+
+FIND_LIBRARY(LDAP_LIBRARY NAMES ldap
+                          PATHS /usr/lib /lib /usr/local/lib /usr/share/lib /opt/lib /opt/share/lib /var/lib /usr/lib64 /lib64 /usr/local/lib64 /usr/share/lib64 /opt/lib64 /opt/share/lib64 /var/lib64
+                          DOC "Try and find libldap")
+
+
+IF (LDAP_LIBRARY)
+	get_filename_component(LDAP_LIBRARY_DIRS ${LDAP_LIBRARY} PATH)
+	FIND_LIBRARY(LBER_LIBRARY NAMES lber
+  	                        PATHS /usr/lib /lib /usr/local/lib /usr/share/lib /opt/lib /opt/share/lib /var/lib /usr/lib64 /lib64 /usr/local/lib64 /usr/share/lib64 /opt/lib64 /opt/share/lib64 /var/lib64 ${LDAP_LIBRARY_DIRS}
+    	                      DOC "Try and find liblber")
+ELSE (LDAP_LIBRARY)
+	FIND_LIBRARY(LBER_LIBRARY NAMES lber
+  	                        PATHS /usr/lib /lib /usr/local/lib /usr/share/lib /opt/lib /opt/share/lib /var/lib /usr/lib64 /lib64 /usr/local/lib64 /usr/share/lib64 /opt/lib64 /opt/share/lib64 /var/lib64
+    	                      DOC "Try and find liblber")
+ENDIF (LDAP_LIBRARY)
+
+
+
+
+IF (LBER_LIBRARY)
+	SET( LIBLBER_FOUND 1 )  
+	get_filename_component(LBER_LIBRARY_DIRS ${LBER_LIBRARY} PATH)
+	MESSAGE(STATUS "  Found ${LBER_LIBRARY}")
+ELSE(LBER_LIBRARY)
+	MESSAGE( STATUS "   Could NOT find liblber.")
+ENDIF (LBER_LIBRARY)
+
+
+
+
+IF (LDAP_INCLUDE_DIR AND LDAP_LIBRARY)
+	SET( LIBLDAP_FOUND 1 )  
+  MESSAGE(STATUS "  Found ${LDAP_LIBRARY}")
+ELSE (LDAP_INCLUDE_DIR AND LDAP_LIBRARY)
+	IF ( LibLdap_FIND_REQUIRED )
+	  MESSAGE( FATAL_ERROR "  Could NOT find libldap.  The ldap plugin needs this library.")
+	ELSE ( LibLdap_FIND_REQUIRED )
+		MESSAGE( STATUS "   Could NOT find libldap.")
+	ENDIF ( LibLdap_FIND_REQUIRED )
+ENDIF (LDAP_INCLUDE_DIR AND LDAP_LIBRARY)
+
diff --git a/cmake/modules/FindLibMozLdap.cmake b/cmake/modules/FindLibMozLdap.cmake
new file mode 100644
index 0000000..6c814ec
--- /dev/null
+++ b/cmake/modules/FindLibMozLdap.cmake
@@ -0,0 +1,96 @@
+# Try and find libmozldap.
+# As soon as libmozldap has been found, the following variables will be defined:
+#
+# LIBMOZLDAP_FOUND (this is or is not #defined)
+# MOZLDAP_INCLUDE_DIR:DIRPATH
+# MOZLDAP_LIBRARY:FILEPATH
+#
+#
+# Copyright (c) 2009 Juergen Leising 
+#
+# Redistribution and use is allowed according to the terms of the New
+# BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+MESSAGE(STATUS "checking for libmozldap...")
+
+# Prepare for using pkg-config
+INCLUDE( FindPkgConfig )
+
+IF ( LibMozLdap_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( LibMozLdap_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )
+ENDIF ( LibMozLdap_FIND_REQUIRED )
+
+FIND_PROGRAM( PKGCONFIG_EXECUTABLE NAMES pkg-config )
+
+
+
+# Search for the header files and the libraries by means of pkg-config
+IF ( PKG_CONFIG_FOUND )
+	MESSAGE (STATUS "  Trying to invoke pkg-config...")
+	# PKG_SEARCH_MODULE ( LIBMOZLDAP ${_pkgconfig_REQUIRED} mozldap )
+	PKG_CHECK_MODULES ( LIBMOZLDAP ${_pkgconfig_REQUIRED} mozldap )
+	IF ( LIBMOZLDAP_FOUND )
+		MESSAGE (STATUS "    pkg-config found mozldap.")
+	ELSE ( LIBMOZLDAP_FOUND ) 
+		MESSAGE (STATUS "    pkg-config did NOT find mozldap.")
+	ENDIF ( LIBMOZLDAP_FOUND )
+ENDIF ( PKG_CONFIG_FOUND )
+ 
+
+
+
+# Manually searching for header and library.
+# Only, if it has not been found, yet.  Which would also be the case,
+# if pkg-config could not have been found.
+IF ( NOT MOZLDAP_INCLUDE_DIR )
+	MESSAGE (STATUS "  Falling back to searching for mozldap/ldap.h without pkg-config" )
+	FIND_PATH(MOZLDAP_INCLUDE_DIR NAMES mozldap/ldap.h
+                          PATHS /include /usr/include /usr/local/include /usr/share/include /opt/include 
+                          DOC "Try and find the header file mozldap/ldap.h.")
+ENDIF ( NOT MOZLDAP_INCLUDE_DIR )
+
+
+IF ( NOT LIBMOZLDAP_LIBRARIES )
+	MESSAGE (STATUS "  Falling back to searching for libldap60 and libssldap60 without pkg-config" )
+
+	FIND_LIBRARY(MOZLDAP_LIBRARY NAMES ldap60
+                          PATHS /usr/lib /lib /usr/local/lib /usr/share/lib /opt/lib /opt/share/lib /var/lib /usr/lib64 /lib64 /usr/local/lib64 /usr/share/lib64 /opt/lib64 /opt/share/lib64 /var/lib64
+                          DOC "Try and find libldap60 from Mozilla.")
+
+	FIND_LIBRARY(MOZSSLDAP_LIBRARY NAMES ssldap60
+                          PATHS /usr/lib /lib /usr/local/lib /usr/share/lib /opt/lib /opt/share/lib /var/lib /usr/lib64 /lib64 /usr/local/lib64 /usr/share/lib64 /opt/lib64 /opt/share/lib64 /var/lib64
+                          DOC "Try and find libssldap60 from Mozilla.")
+
+	SET ( LIBMOZLDAP_LIBRARIES ${MOZLDAP_LIBRARY} ${MOZSSLDAP_LIBRARY} )
+
+ENDIF ( NOT LIBMOZLDAP_LIBRARIES )
+
+
+
+
+
+# Reviewing the results
+IF (MOZLDAP_INCLUDE_DIR AND MOZLDAP_LIBRARY)
+	SET( LIBMOZLDAP_FOUND 1 )
+  get_filename_component(MOZLDAP_LIBRARY_DIRS ${MOZLDAP_LIBRARY} PATH)
+  MESSAGE(STATUS "  Found ${MOZLDAP_LIBRARY}")
+ELSE (MOZLDAP_INCLUDE_DIR AND MOZLDAP_LIBRARY)
+	IF ( LibMozLdap_FIND_REQUIRED )
+	  MESSAGE( FATAL_ERROR "  Could NOT find libldap60 from Mozilla.  The ldap plugin needs this library.")
+	ELSE ( LibMozLdap_FIND_REQUIRED )
+		MESSAGE( STATUS "  Could NOT find libldap60 from Mozilla." )
+		MESSAGE( STATUS "  LIBMOZLDAP_INCLUDE_DIR  = ${LIBMOZLDAP_INCLUDE_DIR}" )
+		MESSAGE( STATUS "  LIBMOZLDAP_INCLUDE_DIRS = ${LIBMOZLDAP_INCLUDE_DIRS}" )
+		MESSAGE( STATUS "  LIBMOZLDAP_LIBRARY = ${LIBMOZLDAP_LIBRARY}" )
+		MESSAGE( STATUS "  LIBMOZLDAP_LIBRARY_DIRS = ${LIBMOZLDAP_LIBRARY_DIRS}" )
+		MESSAGE( STATUS "  LIBMOZLDAP_LIBDIR = ${LIBMOZLDAP_LIBDIR}" )
+	
+
+	ENDIF ( LibMozLdap_FIND_REQUIRED )
+ENDIF (MOZLDAP_INCLUDE_DIR AND MOZLDAP_LIBRARY)
+
diff --git a/cmake/modules/FindLibNeon.cmake b/cmake/modules/FindLibNeon.cmake
new file mode 100644
index 0000000..7dffb7b
--- /dev/null
+++ b/cmake/modules/FindLibNeon.cmake
@@ -0,0 +1,147 @@
+# - Try and find libneon
+# Once done this will define
+#
+#  NEON_FOUND - system has libneon
+#  NEON_INCLUDE_DIR - the libneon include directory
+#  NEON_LIBRARIES - Link these to use libneon
+#  NEON_DEFINITIONS - Compiler switches required for using libneon
+
+# Copyright (c) 2011, Juergen Leising, 
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+IF (NEON_INCLUDE_DIR AND NEON_LIBRARIES)
+    SET(NEON_FIND_QUIETLY TRUE)
+ENDIF (NEON_INCLUDE_DIR AND NEON_LIBRARIES)
+
+# Useful for finding out CPPFLAGS, LDFLAGS and features:
+FIND_PROGRAM( NEON_CONFIG_EXECUTABLE NAMES neon-config )
+
+
+
+# 1. Search for the include dirs and for the library by means of cmake
+FIND_PATH(NEON_INCLUDE_DIR NAMES neon/ne_session.h 
+                            PATHS /include /usr/include /usr/local/include /usr/share/include /opt/include /include/neon /usr/include/neon /usr/local/include/neon /usr/share/include/neon /opt/include/neon
+         )
+
+FIND_LIBRARY(NEON_LIBRARIES NAMES neon )
+
+
+
+# 2. Search for the include dirs and for the library by means of neon-config,
+#    if necessary and if possible
+IF (NOT NEON_INCLUDE_DIR OR NOT NEON_LIBRARIES)
+	
+	IF ( NEON_CONFIG_EXECUTABLE )
+		EXECUTE_PROCESS( COMMAND ${NEON_CONFIG_EXECUTABLE} "--libs"
+		                 OUTPUT_VARIABLE NEON_LIBRARIES 
+		                 OUTPUT_STRIP_TRAILING_WHITESPACE )
+		               
+		EXECUTE_PROCESS( COMMAND ${NEON_CONFIG_EXECUTABLE} "--cflags"
+		                 OUTPUT_VARIABLE NEON_DEFINITIONS 
+		                 OUTPUT_STRIP_TRAILING_WHITESPACE )	
+
+		EXECUTE_PROCESS( COMMAND ${NEON_CONFIG_EXECUTABLE} "--cflags"
+		                 OUTPUT_VARIABLE NEON_INCLUDE_DIR
+		                 OUTPUT_STRIP_TRAILING_WHITESPACE )
+
+	ELSE ( NEON_CONFIG_EXECUTABLE )
+		MESSAGE(STATUS "neon-config could NOT be found.")
+
+	ENDIF ( NEON_CONFIG_EXECUTABLE )
+	
+ENDIF (NOT NEON_INCLUDE_DIR OR NOT NEON_LIBRARIES)
+
+
+
+# 3. Search for the include dirs and for the library by means of pkg-config,
+#    if necessary and if possible
+IF (NOT NEON_INCLUDE_DIR OR NOT NEON_LIBRARIES)
+	FIND_PROGRAM( PKGCONFIG_EXECUTABLE NAMES pkg-config )
+
+	IF ( PKG_CONFIG_FOUND )
+  	MESSAGE (STATUS "  Trying to invoke pkg-config...")
+  	PKG_CHECK_MODULES ( NEON ${_pkgconfig_REQUIRED} neon )
+	  IF ( NEON_FOUND )
+  	  MESSAGE (STATUS "    pkg-config found libneon.")
+			SET (NEON_INCLUDE_DIR ${NEON_INCLUDE_DIR} )
+	  ELSE ( NEON_FOUND ) 
+  	  MESSAGE (STATUS "    pkg-config did NOT find libneon.")
+	  ENDIF ( NEON_FOUND )
+	ENDIF ( PKG_CONFIG_FOUND )
+
+ENDIF (NOT NEON_INCLUDE_DIR OR NOT NEON_LIBRARIES)
+
+IF (NOT NEON_INCLUDE_DIR)
+	SET(NEON_FOUND FALSE)
+ENDIF (NOT NEON_INCLUDE_DIR)
+
+
+
+
+
+# Handle the QUIETLY and REQUIRED arguments and set NEON_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(NEON DEFAULT_MSG NEON_LIBRARIES NEON_INCLUDE_DIR)
+
+
+# The pkg-config and the neon-config are all a bit buggy,
+# aren't they? At least, when it comes to cross-compiling... 
+# Or is it the FIND_PACKAGE_HANDLE_STANDARD_ARGS macro? Don't know :-/
+# Therefore:
+
+# Safety check no. 1: 
+IF (NOT NEON_INCLUDE_DIR)
+	SET(NEON_FOUND 0)
+ENDIF (NOT NEON_INCLUDE_DIR)
+
+# Safety check no. 2
+IF (NEON_FOUND)
+	INCLUDE(CheckLibraryExists)
+	CHECK_LIBRARY_EXISTS(${NEON_LIBRARIES} ne_session_create "" NE_SESSION_CREATE_EXISTS)
+	IF (NOT NE_SESSION_CREATE_EXISTS)
+		MESSAGE(STATUS "NEON_INCLUDE_DIR = \"${NEON_INCLUDE_DIR}\"")
+		MESSAGE(STATUS "NEON_LIBRARIES = \"${NEON_LIBRARIES}\"")
+		MESSAGE(STATUS "NEON_DEFINITIONS = \"${NEON_DEFINITIONS}\"")
+		SET(NEON_FOUND 0)
+	ENDIF (NOT NE_SESSION_CREATE_EXISTS)
+ENDIF (NEON_FOUND)
+
+
+
+# Reporting
+IF (NEON_FOUND)
+	MESSAGE(STATUS "NEON_INCLUDE_DIR = \"${NEON_INCLUDE_DIR}\"")
+	MESSAGE(STATUS "NEON_LIBRARIES = \"${NEON_LIBRARIES}\"")
+	MESSAGE(STATUS "NEON_DEFINITIONS = \"${NEON_DEFINITIONS}\"")
+
+	IF ( NEON_CONFIG_EXECUTABLE )
+		# neon-config --support TS_SSL
+		EXECUTE_PROCESS( COMMAND ${NEON_CONFIG_EXECUTABLE} "--support" "ts_ssl"
+		                 RESULT_VARIABLE TS_SSL 
+		                 OUTPUT_STRIP_TRAILING_WHITESPACE )
+
+		IF (TS_SSL EQUAL 0)
+			MESSAGE(STATUS "libneon has been compiled with the --enable-threadsafe-ssl flag. You can use SSL/TLS in a multi-threaded application.")
+			SET( THREAD_SAFE_SSL 1 )
+		ELSE (TS_SSL EQUAL 0) 	
+			MESSAGE(STATUS "libneon has NOT been compiled with the --enable-threadsafe-ssl flag. You should NOT use SSL/TLS in a multithreaded application.")
+			SET( THREAD_SAFE_SSL 0 )
+		ENDIF (TS_SSL EQUAL 0)
+
+	ENDIF ( NEON_CONFIG_EXECUTABLE )
+
+ELSE (NEON_FOUND)	
+	IF (LibNeon_FIND_REQUIRED)
+		MESSAGE( FATAL_ERROR "Could NOT find libneon" )	
+	ELSE (LibNeon_FIND_REQUIRED)
+		MESSAGE( STATUS "Could NOT find libneon" )
+	ENDIF (LibNeon_FIND_REQUIRED)
+	
+ENDIF (NEON_FOUND)
+
+MARK_AS_ADVANCED(NEON_INCLUDE_DIR NEON_LIBRARIES)
+
diff --git a/cmake/modules/FindLibSASL2.cmake b/cmake/modules/FindLibSASL2.cmake
new file mode 100644
index 0000000..e805c58
--- /dev/null
+++ b/cmake/modules/FindLibSASL2.cmake
@@ -0,0 +1,37 @@
+# Try and find libsasl2.
+# As soon as libsasl2 has been found, the following variables will be defined:
+#
+# LIBSASL2_FOUND
+# SASL2_INCLUDE_DIR
+# SASL2_LIBRARY:FILEPATH
+#
+# Copyright (c) 2009 Juergen Leising 
+#
+# Redistribution and use is allowed according to the terms of the New
+# BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+MESSAGE(STATUS "checking for libsasl2...")
+
+FIND_PATH(SASL2_INCLUDE_DIR NAMES sasl/sasl.h
+                             PATHS /include /usr/include /usr/local/include /usr/share/include /opt/include 
+                             DOC "Try and find the header file sasl/sasl.h")
+
+FIND_LIBRARY(SASL2_LIBRARY NAMES sasl2
+                           PATHS /usr/lib /lib /usr/local/lib /usr/share/lib /opt/lib /opt/share/lib /var/lib
+                           DOC "Try and find libsasl2")
+
+IF (SASL2_INCLUDE_DIR AND SASL2_LIBRARY)
+	SET (LIBSASL2_FOUND 1)
+  get_filename_component(SASL2_LIBRARY_DIRS ${SASL2_LIBRARY} PATH)
+  MESSAGE(STATUS "  Found ${SASL2_LIBRARY}")
+ELSE (SASL2_INCLUDE_DIR AND SASL2_LIBRARY)
+	IF ( LibSASL2_FIND_REQUIRED	)
+	  MESSAGE( FATAL_ERROR "  Could NOT find libsasl2. The ldap plugin needs this library." )
+	ELSE ( LibSASL2_FIND_REQUIRED )
+		MESSAGE( STATUS "  Could NOT find libsasl2.")
+	ENDIF ( LibSASL2_FIND_REQUIRED )
+ENDIF (SASL2_INCLUDE_DIR AND SASL2_LIBRARY)
+
+
diff --git a/cmake/modules/FindLibSoup2.cmake b/cmake/modules/FindLibSoup2.cmake
new file mode 100644
index 0000000..68e8fba
--- /dev/null
+++ b/cmake/modules/FindLibSoup2.cmake
@@ -0,0 +1,167 @@
+# - Try to find libsoup
+# Find libsoup headers, libraries and the answer to all questions.
+#
+#  LIBSOUP2_FOUND                True if libsoup2 got found
+#  LIBSOUP2_INCLUDE_DIRS         Location of libsoup2 headers 
+#  LIBSOUP2_LIBRARIES            List of libaries to use libsoup2
+#  LIBSOUP2_LIBRARY_DIRS         Location of libsoup2 library
+#
+#  LIBSOUP22_FOUND               True if libsoup2.2 got found
+#  LIBSOUP22_INCLUDE_DIRS        Location of libsoup2.2 headers 
+#  LIBSOUP22_LIBRARIES           List of libaries to use libsoup2.2
+#  LIBSOUP22_LIBRARY_DIRS        Location of libsoup2.2 library
+#
+#  LIBSOUP24_FOUND               True if libsoup2.4 got found
+#  LIBSOUP24_INCLUDE_DIRS        Location of libsoup2.4 headers 
+#  LIBSOUP24_LIBRARIES           List of libaries to use libsoup2.4
+#  LIBSOUP24_LIBRARY_DIRS        Location of libsoup2.4 library
+#
+#  Set LIBSOUP2_MIN_VERSION to find libsoup2.2 or libsoup2.4 if only 
+#  one of both libraries is supported
+#
+#  Don't use LIBSOUP2_MIN_VERSION if you want to support 
+#  libsoup2.2 and libsoup2.4. 
+#  Instead use LIBSPOUP22_MIN_VERSION and LIBSPOUP24_MIN_VERSION.
+#
+#  Set LIBSPOUP22_MIN_VERSION to find libsoup2.2 which version is
+#  greater than LIBSPOUP22_MIN_VERSION
+#
+#  Set LIBSPOUP24_MIN_VERSION to find libsoup2.4 which version is
+#  greater than LIBSPOUP24_MIN_VERSION
+#
+#  WARNING: It is not possible to set LIBSPOUP22_MIN_VERSION 
+#  and support any version of libsoup2.4 at the same time.
+#  In this situation you have to set LIBSPOUP24_MIN_VERSION also.
+#  The same applies to LIBSPOUP24_MIN_VERSION and libsoup2.2.
+#
+#  Copyright (c) 2007 Daniel Gollub 
+#  Copyright (c) 2008 Bjoern Ricks  
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( LibSoup2_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( LibSoup2_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( LibSoup2_FIND_REQUIRED )
+
+IF ( LIBSOUP2_MIN_VERSION )
+	STRING(REGEX REPLACE "^(2)(\\.)([0-9]*)(\\.?)(.*)" "\\3" LIBSOUP2_VERSION_MINOR "${LIBSOUP2_MIN_VERSION}")
+	IF ( LIBSOUP2_VERSION_MINOR EQUAL "2" )
+		SET( LIBSOUP22_MIN_VERSION "${LIBSOUP2_MIN_VERSION}" )
+	ELSE ( LIBSOUP2_VERSION_MINOR EQUAL "2" )
+		SET( LIBSOUP24_MIN_VERSION "${LIBSOUP2_MIN_VERSION}" )
+	ENDIF ( LIBSOUP2_VERSION_MINOR EQUAL "2" )
+ENDIF ( LIBSOUP2_MIN_VERSION )
+
+# try to find libsoup2.2>=LIBSOUP22_MIN_VERSION
+IF ( LIBSOUP22_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBSOUP22 libsoup-2.2>=${LIBSOUP22_MIN_VERSION} libsoup2>=${LIBSOUP22_MIN_VERSION} )
+ENDIF ( LIBSOUP22_MIN_VERSION )
+
+# try to find libsoup2.4>=LIBSOUP24_MIN_VERSION
+IF ( LIBSOUP24_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBSOUP24 libsoup-2.4>=${LIBSOUP24_MIN_VERSION} libsoup2>=${LIBSOUP24_MIN_VERSION} )
+ENDIF ( LIBSOUP24_MIN_VERSION )	
+
+# try to find any version of libsoup2.4 if LIBSOUP22_MIN_VERSION is not set
+IF ( NOT LIBSOUP24_FOUND AND NOT LIBSOUP22_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBSOUP24 libsoup-2.4 libsoup2 )
+ENDIF ( NOT LIBSOUP24_FOUND AND NOT LIBSOUP22_MIN_VERSION)
+
+# try to find any version of libsoup2.2 if LIBSOUP24_MIN_VERSION is not set
+IF ( NOT LIBSOUP22_FOUND AND NOT LIBSOUP24_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBSOUP22 libsoup-2.2 libsoup2 )
+ENDIF ( NOT LIBSOUP22_FOUND AND NOT LIBSOUP24_MIN_VERSION)
+
+# set LIBSOUP2_ variables
+IF ( LIBSOUP24_FOUND )
+	# prefer libsoup2.4 to libsoup2.2 if both are found
+	SET( LIBSOUP2_FOUND ${LIBSOUP24_FOUND} CACHE INTERNAL "" )
+	SET( LIBSOUP2_INCLUDE_DIRS ${LIBSOUP24_INCLUDE_DIRS} CACHE INTERNAL "" )
+	SET( LIBSOUP2_LIBRARIES ${LIBSOUP24_LIBRARIES} CACHE INTERNAL "" )
+	SET( LIBSOUP2_LIBRARY_DIRS ${LIBSOUP24_LIBRARY_DIRS} CACHE INTERNAL "" )
+	SET( LIBSOUP2_VERSION ${LIBSOUP24_VERSION} CACHE INTERNAL "" )
+ELSEIF ( LIBSOUP22_FOUND )
+	SET( LIBSOUP2_FOUND ${LIBSOUP22_FOUND} CACHE INTERNAL "" )
+	SET( LIBSOUP2_INCLUDE_DIRS ${LIBSOUP22_INCLUDE_DIRS} CACHE INTERNAL "" )
+	SET( LIBSOUP2_LIBRARIES ${LIBSOUP22_LIBRARIES} CACHE INTERNAL "" )
+	SET( LIBSOUP2_LIBRARY_DIRS ${LIBSOUP22_LIBRARY_DIRS} CACHE INTERNAL "" )
+	SET( LIBSOUP2_VERSION ${LIBSOUP22_VERSION} CACHE INTERNAL "" )
+ELSEIF( PKG_CONFIG_FOUND AND LibSoup2_FIND_REQUIRED )
+	# raise an error if both libs are not found 
+	# and FIND_PACKAGE( LibSoup2 REQUIRED ) was called
+	MESSAGE( SEND_ERROR "package libsoup2 not found" )
+ENDIF ( LIBSOUP24_FOUND )
+
+IF( NOT LIBSOUP2_FOUND AND NOT PKG_CONFIG_FOUND )
+	# WARNING:
+	# This case is executed if pkg-config isn't installed.
+	# Currently in this case it is only checked if libsoup2.2 is available.
+	# Therefore please don't use this cmake module without pkg-config!
+	FIND_PATH( _libsoup2_include_DIR libsoup/soup.h PATH_SUFFIXES libsoup libsoup-2.2 )
+	FIND_LIBRARY( _libsoup2_LIBRARY soup-2.2)
+
+	IF ( _libsoup2_include_DIR AND _libsoup2_LIBRARY )
+		SET ( _libsoup2_FOUND TRUE )
+	ENDIF ( _libsoup2_include_DIR AND _libsoup2_LIBRARY )
+
+	IF ( _libsoup2_FOUND )
+		SET ( LIBSOUP2_INCLUDE_DIRS ${_libsoup2_include_DIR} )
+		SET ( LIBSOUP2_LIBRARIES ${_libsoup2_LIBRARY} )
+	
+		# find requited glib2
+		IF( NOT GLIB2_FOUND )
+			FIND_PACKAGE( GLIB2 REQUIRED )
+			IF ( GLIB2_FOUND )
+				SET ( LIBSOUP2_INCLUDE_DIRS ${LIBSOUP2_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} )
+				SET ( LIBSOUP2_LIBRARIES ${LIBSOUP2_LIBRARIES} ${GLIB2_LIBRARIES} )
+			ENDIF ( GLIB2_FOUND )
+		ENDIF( NOT GLIB2_FOUND )
+		
+		# find required libxml2
+		IF( NOT LIBXML2_FOUND )
+			FIND_PACKAGE( LibXml2 REQUIRED )
+			IF ( LIBXML2_FOUND )
+				SET ( LIBSOUP2_INCLUDE_DIRS ${LIBSOUP2_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIRS} )
+				SET ( LIBSOUP2_LIBRARIES ${LIBSOUP2_LIBRARIES} ${LIBXML2_LIBRARIES} )
+			ENDIF( LIBXML2_FOUND )
+		ENDIF( NOT LIBXML2_FOUND )
+		
+		# find required gnutls
+		IF( NOT GNUTLS_FOUND )
+			FIND_PACKAGE( GNUTLS REQUIRED )
+			IF ( GNUTLS_FOUND )
+				SET ( LIBSOUP2_INCLUDE_DIRS ${LIBSOUP2_INCLUDE_DIRS} ${GNUTLS_INCLUDE_DIRS} )
+				SET ( LIBSOUP2_LIBRARIES ${LIBSOUP2_LIBRARIES} ${GNUTLS_LIBRARIES} )
+			ENDIF( GNUTLS_FOUND )
+		ENDIF( NOT GNUTLS_FOUND )
+	ENDIF ( _libsoup2_FOUND )
+
+	MARK_AS_ADVANCED( _libsoup2_include_DIR  _libsoup2_LIBRARY )
+
+	# Report results
+	IF ( LIBSOUP2_LIBRARIES AND LIBSOUP2_INCLUDE_DIRS AND _libsoup2_FOUND )	
+		SET( LIBSOUP2_FOUND 1 )
+		IF ( NOT LibSoup2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libsoup2: ${_libsoup2_LIBRARY}" )
+		ENDIF ( NOT LibSoup2_FIND_QUIETLY )
+	ELSE ( LIBSOUP2_LIBRARIES AND LIBSOUP_INCLUDE_DIRS AND _libsoup2_FOUND )	
+		IF ( LibSoup2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libsoup2" )
+		ELSE ( LibSoup2_FIND_REQUIRED )
+			IF ( NOT LibSoup2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libsoup2" )	
+			ENDIF ( NOT LibSoup2_FIND_QUIETLY )
+		ENDIF ( LibSoup2_FIND_REQUIRED )
+	ENDIF ( LIBSOUP2_LIBRARIES AND LIBSOUP2_INCLUDE_DIRS AND _libsoup2_FOUND )
+ENDIF( NOT LIBSOUP2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBSOUP2_LIBRARIES LIBSOUP2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindLibSyncMl.cmake b/cmake/modules/FindLibSyncMl.cmake
new file mode 100644
index 0000000..3ebe07f
--- /dev/null
+++ b/cmake/modules/FindLibSyncMl.cmake
@@ -0,0 +1,151 @@
+# - Try to find libsyncml
+# Find libsyncml headers, libraries and the answer to all questions.
+#
+#  LIBSYNCML_FOUND               True if libsyncml got found
+#  LIBSYNCML_INCLUDE_DIRS         Location of libsyncml headers 
+#  LIBSYNCML_LIBRARIES           List of libaries to use libsyncml
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+# Take care about libsyncml-x.y.pc settings
+IF ( LibSyncMl_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( LibSyncMl_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( LibSyncMl_FIND_REQUIRED )
+
+# determine API generation
+
+SET( LIBSYNCML_PC "libsyncml-1.0" )
+PKG_SEARCH_MODULE( LIBSYNCML ${_pkgconfig_REQUIRED} libsyncml-3.0 )
+IF ( LIBSYNCML_FOUND )
+	SET ( LIBSYNCML_FOUND FALSE )
+	SET( LIBSYNCML_PC "libsyncml-3.0" )
+ENDIF ( LIBSYNCML_FOUND )
+
+# check for libsyncml-x.y.pc
+
+IF ( LIBSYNCML_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBSYNCML ${_pkgconfig_REQUIRED} ${LIBSYNCML_PC}>=${LIBSYNCML_MIN_VERSION} )
+ELSE( LIBSYNCML_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBSYNCML ${_pkgconfig_REQUIRED} ${LIBSYNCML_PC} )
+ENDIF ( LIBSYNCML_MIN_VERSION )
+
+
+# Look for libsyncml include dir and libraries without pkg-config...
+IF ( NOT LIBSYNCML_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libsyncml_include_DIR libsyncml/syncml.h 
+			PATH_SUFFIXES ${LIBSYNCML_PC}
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ 
+	)
+
+	FIND_LIBRARY( _libsyncml_link_DIR syncml 
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 
+	)
+
+	IF ( _libsyncml_include_DIR AND _libsyncml_link_DIR )
+		SET ( _libsyncml_FOUND TRUE )
+	ENDIF ( _libsyncml_include_DIR AND _libsyncml_link_DIR )
+
+	IF ( _libsyncml_FOUND )
+		SET ( LIBSYNCML_INCLUDE_DIRS ${_libsyncml_include_DIR} )
+		SET ( LIBSYNCML_LIBRARIES ${_libsyncml_link_DIR} )
+	ENDIF ( _libsyncml_FOUND )
+
+	# Handle dependencies
+	IF( NOT LIBSOUP2_FOUND )
+		SET ( LIBSOUP2_MIN_VERSION "2.2.91" )
+		FIND_PACKAGE( LibSoup2 )
+		IF ( LIBSOUP2_FOUND )
+			SET ( LIBSYNCML_INCLUDE_DIRS ${LIBSYNCML_INCLUDE_DIRS} ${LIBSOUP2_INCLUDE_DIRS} )
+			SET ( LIBSYNCML_LIBRARIES ${LIBSYNCML_LIBRARIES} ${LIBSOUP2_LIBRARIES} )
+		ENDIF( LIBSOUP2_FOUND )
+	ENDIF( NOT LIBSOUP2_FOUND )
+	IF( NOT OPENOBEX_FOUND )
+		SET ( OPENOBEX_MIN_VERSION "1.1" )
+		FIND_PACKAGE( OpenObex )
+		IF ( OPENOBEX_FOUND )
+			SET ( LIBSYNCML_INCLUDE_DIRS ${LIBSYNCML_INCLUDE_DIRS} ${OPENOBEX_INCLUDE_DIRS} )
+			SET ( LIBSYNCML_LIBRARIES ${LIBSYNCML_LIBRARIES} ${OPENOBEX_LIBRARIES} )
+		ENDIF( OPENOBEX_FOUND )
+	ENDIF( NOT OPENOBEX_FOUND )
+	IF( NOT LIBWBXML2_FOUND )
+		FIND_PACKAGE( LibWbxml2 REQUIRED )
+		IF ( LIBWBXML2_FOUND )
+			SET ( LIBSYNCML_INCLUDE_DIRS ${LIBSYNCML_INCLUDE_DIRS} ${LIBWBXML2_INCLUDE_DIRS} )
+			SET ( LIBSYNCML_LIBRARIES ${LIBSYNCML_LIBRARIES} ${LIBWBXML2_LIBRARIES} )
+		ENDIF( LIBWBXML2_FOUND )
+	ENDIF( NOT LIBWBXML2_FOUND )
+	IF( NOT BLUEZ_FOUND )
+		FIND_PACKAGE( BlueZ )
+		IF ( BLUEZ_FOUND )
+			SET ( LIBSYNCML_INCLUDE_DIRS ${LIBSYNCML_INCLUDE_DIRS} ${BLUEZ_INCLUDE_DIRS} )
+			SET ( LIBSYNCML_LIBRARIES ${LIBSYNCML_LIBRARIES} ${BLUEZ_LIBRARIES} )
+		ENDIF( BLUEZ_FOUND )
+	ENDIF( NOT BLUEZ_FOUND )
+	IF( NOT LIBXML2_FOUND )
+		FIND_PACKAGE( LibXml2 REQUIRED )
+		IF ( LIBXML2_FOUND )
+			SET ( LIBSYNCML_INCLUDE_DIRS ${LIBSYNCML_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIRS} )
+			SET ( LIBSYNCML_LIBRARIES ${LIBSYNCML_LIBRARIES} ${LIBXML2_LIBRARIES} )
+		ENDIF( LIBXML2_FOUND )
+	ENDIF( NOT LIBXML2_FOUND )
+	IF ( NOT GLIB2_FOUND )
+                FIND_PACKAGE( GLIB2 REQUIRED)
+
+                IF ( GOBJECT2_FOUND )
+                        SET ( LIBSYNCML_INCLUDE_DIRS ${LIBSYNCML_INCLUDE_DIRS} ${GOBJECT2_INCLUDE_DIR} )
+                        SET ( LIBSYNCML_LIBRARIES ${LIBSYNCML_LIBRARIES} ${GOBJECT2_LIBRARY} )
+                ENDIF ( GOBJECT2_FOUND )
+                IF ( GTHREAD2_FOUND )
+                        SET ( LIBSYNCML_INCLUDE_DIRS ${LIBSYNCML_INCLUDE_DIRS} ${GTHREAD2_INCLUDE_DIR} )
+                        SET ( LIBSYNCML_LIBRARIES ${LIBSYNCML_LIBRARIES} ${GTHREAD2_LIBRARY} )
+                ENDIF ( GTHREAD2_FOUND )
+                IF ( GLIB2_FOUND )
+                        SET ( LIBSYNCML_INCLUDE_DIRS ${LIBSYNCML_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} ${GLIBCONFIG_INCLUDE_DIR} )
+                        SET ( LIBSYNCML_LIBRARIES ${LIBSYNCML_LIBRARIES} ${GLIB2_LIBRARIES} )
+                ENDIF ( GLIB2_FOUND )
+        ENDIF ( NOT GLIB2_FOUND )
+
+
+	# Report results
+	IF ( LIBSYNCML_LIBRARIES AND LIBSYNCML_INCLUDE_DIRS )	
+		SET( LIBSYNCML_FOUND 1 )
+		IF ( NOT LibSyncMl_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libsyncml: ${LIBSYNCML_LIBRARIES}" )
+		ENDIF ( NOT LibSyncMl_FIND_QUIETLY )
+	ELSE ( LIBSYNCML_LIBRARIES AND LIBSYNCML_INCLUDE_DIRS )	
+		IF ( LibSyncMl_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libsyncml" )
+		ELSE ( LibSyncMl_FIND_REQUIRED )
+			IF ( NOT LibSyncMl_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libsyncml" )	
+			ENDIF ( NOT LibSyncMl_FIND_QUIETLY )
+		ENDIF ( LibSyncMl_FIND_REQUIRED )
+	ENDIF ( LIBSYNCML_LIBRARIES AND LIBSYNCML_INCLUDE_DIRS )	
+
+ENDIF ( NOT LIBSYNCML_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBSYNCML_LIBRARIES LIBSYNCML_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindLibUuid.cmake b/cmake/modules/FindLibUuid.cmake
new file mode 100644
index 0000000..cf4bf7f
--- /dev/null
+++ b/cmake/modules/FindLibUuid.cmake
@@ -0,0 +1,51 @@
+# - Try to find LIBUUID 
+# Find LIBUUID headers, libraries and the answer to all questions.
+#
+#  LIBUUID_FOUND               True if libuuid got found
+#  LIBUUID_INCLUDE_DIRS        Location of libuuid headers 
+#  LIBUUID_LIBRARIES           List of libraries to use libuuid 
+#
+# Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( LibUuid_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( LibUuid_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( LibUuid_FIND_REQUIRED )
+
+IF ( LIBUUID_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBUUID ${_pkgconfig_REQUIRED} uuid>=${LIBUUID_MIN_VERSION} )
+ELSE ( LIBUUID_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBUUID ${_pkgconfig_REQUIRED} uuid )
+ENDIF ( LIBUUID_MIN_VERSION )
+
+
+IF( NOT LIBUUID_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( LIBUUID_INCLUDE_DIRS uuid/uuid.h )
+	FIND_LIBRARY( LIBUUID_LIBRARIES uuid)
+
+	# Report results
+	IF ( LIBUUID_LIBRARIES AND LIBUUID_INCLUDE_DIRS )	
+		SET( LIBUUID_FOUND 1 )
+		IF ( NOT LIBUUID_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libuuid: ${LIBUUID_LIBRARIES}" )
+		ENDIF ( NOT LIBUUID_FIND_QUIETLY )
+	ELSE ( LIBUUID_LIBRARIES AND LIBUUID_INCLUDE_DIRS )	
+		IF ( LIBUUID_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libuuid" )
+		ELSE ( LIBUUID_FIND_REQUIRED )
+			IF ( NOT LIBUUID_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libuuid" )	
+			ENDIF ( NOT LIBUUID_FIND_QUIETLY )
+		ENDIF ( LIBUUID_FIND_REQUIRED )
+	ENDIF ( LIBUUID_LIBRARIES AND LIBUUID_INCLUDE_DIRS )
+ENDIF( NOT LIBUUID_FOUND AND NOT PKG_CONFIG_FOUND )
+
+MARK_AS_ADVANCED( LIBUUID_LIBRARIES LIBUUID_INCLUDE_DIRS )
\ No newline at end of file
diff --git a/cmake/modules/FindLibWbxml2.cmake b/cmake/modules/FindLibWbxml2.cmake
new file mode 100644
index 0000000..5f04dd1
--- /dev/null
+++ b/cmake/modules/FindLibWbxml2.cmake
@@ -0,0 +1,86 @@
+# - Try to find libwbxml
+# Find libwbxml headers, libraries and the answer to all questions.
+#
+#  LIBWBXML2_FOUND               True if libwbxml got found
+#  LIBWBXML2_INCLUDE_DIRS        Location of libwbxml headers 
+#  LIBWBXML2_LIBRARIES           List of libaries to use libwbxml
+#
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Bjoern Ricks  
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( LibWbxml2_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( LibWbxml2_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( LibWbxml2_FIND_REQUIRED )
+
+IF ( LIBWBXML2_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBWBXML2 libwbxml2>=${LIBWBXML2_MIN_VERSION} ${_pkgconfig_REQUIRED} )
+ELSE ( LIBWBXML2_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBWBXML2 libwbxml2 ${_pkgconfig_REQUIRED} )
+ENDIF ( LIBWBXML2_MIN_VERSION )
+
+
+IF( NOT LIBWBXML2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libwbxml2_include_DIR wbxml.h
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ )
+	FIND_LIBRARY( _libwbxml2_LIBRARY wbxml2
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 )
+	IF ( _libwbxml2_include_DIR AND _libwbxml2_LIBRARY )
+		SET ( _libwbxml2_FOUND TRUE )
+	ENDIF ( _libwbxml2_include_DIR AND _libwbxml2_LIBRARY )
+
+	IF ( _libwbxml2_FOUND )
+		SET ( LIBWBXML2_INCLUDE_DIRS ${_libwbxml2_include_DIR} )
+		SET ( LIBWBXML2_LIBRARIES ${_libwbxml2_LIBRARY} )
+
+		# find required libexpat
+		IF( NOT EXPAT_FOUND )
+			FIND_PACKAGE( Expat REQUIRED )
+			IF ( EXPAT_FOUND )
+				SET ( LIBWBXML2_INCLUDE_DIRS ${LIBWBXML2_INCLUDE_DIRS} ${EXPAT_INCLUDE_DIRS} )
+				SET ( LIBWBXML2_LIBRARIES ${LIBWBXML2_LIBRARIES} ${EXPAT_LIBRARIES} )
+			ENDIF( EXPAT_FOUND )
+		ENDIF( NOT EXPAT_FOUND )
+	ENDIF( _libwbxml2_FOUND )
+
+	MARK_AS_ADVANCED( _libwbxml2_include_DIR _libwbxml2_LIBRARY )
+
+	# Report results
+	IF ( LIBWBXML2_LIBRARIES AND LIBWBXML2_INCLUDE_DIRS AND _libwbxml2_FOUND )	
+		SET( LIBWBXML_FOUND 1 )
+		IF ( NOT LibWbxml2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libwbxml2: ${_libwbxml2_LIBRARY}" )
+		ENDIF ( NOT LibWbxml2_FIND_QUIETLY )
+	ELSE ( LIBWBXML2_LIBRARIES AND LIBWBXML2_INCLUDE_DIRS AND _libwbxml2_FOUND )	
+		IF ( LibWbxml2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libwbxml2" )
+		ELSE ( LibWbxml2_FIND_REQUIRED )
+			IF ( NOT LibWbxml2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libwbxml2" )	
+			ENDIF ( NOT LibWbxml2_FIND_QUIETLY )
+		ENDIF ( LibWbxml2_FIND_REQUIRED )
+	ENDIF ( LIBWBXML2_LIBRARIES AND LIBWBXML2_INCLUDE_DIRS AND _libwbxml2_FOUND )
+ENDIF( NOT LIBWBXML2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBWBXML2_LIBRARIES LIBWBXML2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindLibXml2.cmake b/cmake/modules/FindLibXml2.cmake
new file mode 100644
index 0000000..126cc9b
--- /dev/null
+++ b/cmake/modules/FindLibXml2.cmake
@@ -0,0 +1,82 @@
+# - Try to find libxml2 
+# Find libxml2 headers, libraries and the answer to all questions.
+#
+#  LIBXML2_FOUND               True if libxml2 got found
+#  LIBXML2_INCLUDE_DIRS        Location of libxml2 headers 
+#  LIBXML2_LIBRARIES           List of libraries to use libxml2
+#  LIBXML2_DEFINITIONS         Definitions to compile libxml2
+#
+# Copyright (c) 2006, Alexander Neundorf, 
+# Copyright (c) 2007 Alban Browaeys 
+# Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about libxml2.pc settings
+IF ( LibXml2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( LibXml2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( LibXml2_FIND_REQUIRED )
+
+IF ( LIBXML2_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBXML2 ${_pkgconfig_REQUIRED} libxml-2.0>=${LIBXML2_MIN_VERSION} )
+ELSE ( LIBXML2_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBXML2 ${_pkgconfig_REQUIRED} libxml-2.0 )
+ENDIF ( LIBXML2_MIN_VERSION )
+
+
+# Look for libxml-2.0 include dir and libraries w/o pkgconfig
+IF ( NOT LIBXML2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _libxml2_include_DIR libxml/xpath.h PATH_SUFFIXES libxml2 
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+	)
+	FIND_LIBRARY( _libxml2_link_DIR NAMES xml2 libxml2 libxml
+		PATHS
+		/opt/local/lib
+		/sw/lib
+		/usr/lib
+		/usr/local/lib
+		/usr/lib64
+		/usr/local/lib64
+		/opt/lib64
+	)
+	IF ( _libxml2_include_DIR AND _libxml2_link_DIR )
+		SET ( _libxml2_FOUND TRUE )
+	ENDIF ( _libxml2_include_DIR AND _libxml2_link_DIR )
+
+
+	IF ( _libxml2_FOUND )
+		SET ( LIBXML2_INCLUDE_DIRS ${_libxml2_include_DIR} )
+		SET ( LIBXML2_LIBRARIES ${_libxml2_link_DIR} )
+	ENDIF ( _libxml2_FOUND )
+
+	# Report results
+	IF ( LIBXML2_LIBRARIES AND LIBXML2_INCLUDE_DIRS AND _libxml2_FOUND )	
+		SET( LIBXML2_FOUND 1 )
+		IF ( NOT LibXml2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libxml2: ${LIBXML2_LIBRARIES} ${LIBXML2_INCLUDE_DIRS}" )
+		ENDIF ( NOT LibXml2_FIND_QUIETLY )
+	ELSE ( LIBXML2_LIBRARIES AND LIBXML2_INCLUDE_DIRS AND _libxml2_FOUND )	
+		IF ( LibXml2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libxml2" )
+		ELSE ( LibXml2_FIND_REQUIRED )
+			IF ( NOT LibXml2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libxml2" )	
+			ENDIF ( NOT LibXml2_FIND_QUIETLY )
+		ENDIF ( LibXml2_FIND_REQUIRED )
+	ENDIF ( LIBXML2_LIBRARIES AND LIBXML2_INCLUDE_DIRS AND _libxml2_FOUND )	
+
+ENDIF ( NOT LIBXML2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindLibXslt.cmake b/cmake/modules/FindLibXslt.cmake
new file mode 100644
index 0000000..28bb0e4
--- /dev/null
+++ b/cmake/modules/FindLibXslt.cmake
@@ -0,0 +1,54 @@
+# - Try to find LibXslt
+# Once done this will define
+#
+#  LIBXSLT_FOUND - system has LibXslt
+#  LIBXSLT_INCLUDE_DIRS - the LibXslt include directory
+#  LIBXSLT_LIBRARIES - Link these to LibXslt
+#  LIBXSLT_DEFINITIONS - Compiler switches required for using LibXslt
+#
+#  Copyright (c) 2006, Alexander Neundorf, 
+#  Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#	
+
+INCLUDE( FindPkgConfig )
+
+IF ( LibXslt_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( LibXslt_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( LibXslt_FIND_REQUIRED )
+
+IF ( LIBXSLT_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBXSLT ${_pkgconfig_REQUIRED} libxslt>=${LIBXSLT_MIN_VERSION} )
+ELSE ( LIBXSLT_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBXSLT ${_pkgconfig_REQUIRED} libxslt )
+ENDIF ( LIBXSLT_MIN_VERSION )
+
+
+IF( NOT LIBXSLT_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( LIBXSLT_INCLUDE_DIRS libxslt/xslt.h )
+	FIND_LIBRARY( LIBXSLT_LIBRARIES xslt libxslt )
+
+	# Report results
+	IF ( LIBXSLT_LIBRARIES AND LIBXSLT_INCLUDE_DIRS )	
+		SET( LIBXSLT_FOUND 1 )
+		IF ( NOT LibXslt_FIND_QUIETLY )
+			MESSAGE( STATUS "Found LibXslt: ${LIBXSLT_LIBRARIES}" )
+		ENDIF ( NOT LibXslt_FIND_QUIETLY )
+	ELSE ( LIBXSLT_LIBRARIES AND LIBXSLT_INCLUDE_DIRS )	
+		IF ( LibXslt_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find LibXslt" )
+		ELSE ( LibXslt_FIND_REQUIRED )
+			IF ( NOT LibXslt_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find LibXslt" )	
+			ENDIF ( NOT LibXslt_FIND_QUIETLY )
+		ENDIF ( LibXslt_FIND_REQUIRED )
+	ENDIF ( LIBXSLT_LIBRARIES AND LIBXSLT_INCLUDE_DIRS )	
+ENDIF( NOT LIBXSLT_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( LIBXSLT_LIBRARIES LIBXSLT_INCLUDE_DIRS )
diff --git a/cmake/modules/FindORBit2.cmake b/cmake/modules/FindORBit2.cmake
new file mode 100644
index 0000000..58af0e7
--- /dev/null
+++ b/cmake/modules/FindORBit2.cmake
@@ -0,0 +1,86 @@
+# - Try to find orbit 
+# Find orbit headers, libraries and the answer to all questions.
+#
+#  ORBIT2_FOUND               True if orbit got found
+#  ORBIT2_INCLUDEDIR          Location of orbit headers 
+#  ORBIT2_LIBRARIES           List of libaries to use orbit 
+#  ORBIT2_DEFINITIONS         Definitions to compile orbit 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+# Take care about ORBit-2.0.pc settings
+IF ( ORBit2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( ORBit2_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( ORBit2_FIND_REQUIRED )
+
+IF ( ORBIT2_MIN_VERSION )
+	pkg_search_module( ORBIT2 ${_pkgconfig_REQUIRED} ORBit-2.0>=${ORBIT2_MIN_VERSION} )
+ELSE ( ORBIT2_MIN_VERSION )
+	pkg_search_module( ORBIT2 ${_pkgconfig_REQUIRED} ORBit-2.0 )
+ENDIF ( ORBIT2_MIN_VERSION )
+
+
+# Look for orbit include dir and libraries w/o pkgconfig
+IF ( NOT ORBIT2_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _orbit2_include_DIR orbit/orbit.h PATH_SUFFIXES orbit-2.0 )
+	FIND_LIBRARY( _orbit2_link_DIR ORBit-2)
+	IF ( _orbit2_include_DIR AND _orbit2_link_DIR )
+		SET ( _orbit2_FOUND TRUE )
+	ENDIF ( _orbit2_include_DIR AND _orbit2_link_DIR )
+
+	IF ( _orbit2_FOUND )
+		SET ( ORBIT2_INCLUDE_DIRS ${_orbit2_include_DIR} )
+		SET ( ORBIT2_LIBRARIES ${_orbit2_link_DIR} )
+	ENDIF ( _orbit2_FOUND )
+
+	IF ( NOT GLIB2_FOUND )
+		FIND_PACKAGE( GLIB2 REQUIRED)
+
+		IF ( GTHREAD2_FOUND )
+			SET ( ORBIT2_INCLUDE_DIRS ${ORBIT2_INCLUDE_DIRS} ${GTHREAD2_INCLUDE_DIR} )
+			SET ( ORBIT2_LIBRARIES ${ORBIT2_LIBRARIES} ${GTHREAD2_LIBRARY} )
+		ENDIF ( GTHREAD2_FOUND )
+		IF ( GOBJECT2_FOUND )
+			SET ( ORBIT2_INCLUDE_DIRS ${ORBIT2_INCLUDE_DIRS} ${GOBJECT2_INCLUDE_DIR} )
+			SET ( ORBIT2_LIBRARIES ${ORBIT2_LIBRARIES} ${GOBJECT2_LIBRARY} )
+		ENDIF ( GOBJECT2_FOUND )
+		IF ( GLIB2_FOUND )
+			SET ( ORBIT2_INCLUDE_DIRS ${ORBIT2_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIR} ${GLIBCONFIG_INCLUDE_DIR} )
+			SET ( ORBIT2_LIBRARIES ${ORBIT2_LIBRARIES} ${GLIB2_LIBRARY} )
+		ENDIF ( GLIB2_FOUND )
+	ENDIF ( NOT GLIB2_FOUND )
+
+	# Report results
+	IF ( ORBIT2_LIBRARIES AND ORBIT2_INCLUDE_DIRS AND _orbit2_FOUND)	
+		SET( ORBIT2_FOUND 1 )
+		IF ( NOT ORBit2_FIND_QUIETLY )
+			MESSAGE( STATUS "Found ORBit2: ${ORBIT2_LIBRARIES} ${ORBIT2_INCLUDE_DIRS}" )
+		ENDIF ( NOT ORBit2_FIND_QUIETLY )
+	ELSE ( ORBIT2_LIBRARIES AND ORBIT2_INCLUDE_DIRS AND _orbit2_FOUND )	
+		IF ( ORBit2_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find ORBit2" )
+		ELSE ( ORBit2_FIND_REQUIRED )
+			IF ( NOT ORBit2_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find ORBit2" )	
+			ENDIF ( NOT ORBit2_FIND_QUIETLY )
+		ENDIF ( ORBit2_FIND_REQUIRED )
+	ENDIF ( ORBIT2_LIBRARIES AND ORBIT2_INCLUDE_DIRS AND _orbit2_FOUND )	
+
+	MARK_AS_ADVANCED( _orbit2_include_DIR _orbit2_link_DIR )
+
+ENDIF ( NOT ORBIT2_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( ORBIT2_LIBRARIES ORBIT2_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindOpenObex.cmake b/cmake/modules/FindOpenObex.cmake
new file mode 100644
index 0000000..a403ba0
--- /dev/null
+++ b/cmake/modules/FindOpenObex.cmake
@@ -0,0 +1,81 @@
+# - Try to find OpenObex
+# Find OpenObex headers, libraries and the answer to all questions.
+#
+#  OPENOBEX_FOUND               True if OpenObex got found
+#  OPENOBEX_INCLUDE_DIRS        Location of OpenObex headers 
+#  OPENOBEX_LIBRARIES           List of libaries to use OpenObex
+#  OPENOBEX_HAVE_TCPOBEX        OpenObex supports Tcp over Obex
+#
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007-2008 Bjoern Ricks  
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( OpenObex_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( OpenObex_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( OpenObex_FIND_REQUIRED )
+
+IF ( OPENOBEX_MIN_VERSION )
+	PKG_SEARCH_MODULE( OPENOBEX openobex>=${OPENOBEX_MIN_VERSION} ${_pkgconfig_REQUIRED} )
+ELSE ( OPENOBEX_MIN_VERSION )
+	PKG_SEARCH_MODULE( OPENOBEX openobex ${_pkgconfig_REQUIRED} )
+ENDIF ( OPENOBEX_MIN_VERSION )
+
+IF( NOT OPENOBEX_FOUND AND NOT PKG_CONFIG_FOUND )
+	# Fallback if pkg-config doesn't exist
+	#MESSAGE( STATUS "FALLBACK" )
+	FIND_PATH( OPENOBEX_INCLUDE_DIRS openobex/obex.h
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/ )
+
+
+	FIND_LIBRARY( OPENOBEX_LIBRARIES openobex
+		PATHS
+		/opt/local/lib
+		/sw/lib
+		/usr/lib
+		/usr/local/lib
+		/usr/lib64
+		/usr/local/lib64
+		/opt/lib64 )
+
+
+	# Report results
+	IF ( OPENOBEX_LIBRARIES AND OPENOBEX_INCLUDE_DIRS )	
+		SET( OPENOBEX_FOUND 1 )
+		IF ( NOT OpenObex_FIND_QUIETLY )
+			MESSAGE( STATUS "Found OpenObex: ${OPENOBEX_LIBRARIES}" )
+		ENDIF ( NOT OpenObex_FIND_QUIETLY )
+	ELSE ( OPENOBEX_LIBRARIES AND OPENOBEX_INCLUDE_DIRS )	
+		IF ( OpenObex_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find OpenObex" )
+		ELSE ( OpenObex_FIND_REQUIRED )
+			IF ( NOT OpenObex_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find OpenObex" )	
+			ENDIF ( NOT OpenObex_FIND_QUIETLY )
+		ENDIF ( OpenObex_FIND_REQUIRED )
+	ENDIF ( OPENOBEX_LIBRARIES AND OPENOBEX_INCLUDE_DIRS )	
+ENDIF( NOT OPENOBEX_FOUND AND NOT PKG_CONFIG_FOUND )
+
+IF ( OPENOBEX_FOUND )
+	INCLUDE(CheckFunctionExists)
+	
+	SET( CMAKE_REQUIRED_INCLUDES ${OPENOBEX_INCLUDE_DIRS} )
+	SET( CMAKE_REQUIRED_LIBRARIES ${OPENOBEX_LIBRARIES} )
+	CHECK_FUNCTION_EXISTS( TcpOBEX_ServerRegister OPENOBEX_HAVE_TCPOBEX )
+	#MESSAGE( STATUS "OpenObex has TCP support: ${OPENOBEX_HAVE_TCPOBEX}" )
+ENDIF( OPENOBEX_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( OPENOBEX_LIBRARIES OPENOBEX_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindOpenSync.cmake b/cmake/modules/FindOpenSync.cmake
new file mode 100644
index 0000000..972f914
--- /dev/null
+++ b/cmake/modules/FindOpenSync.cmake
@@ -0,0 +1,90 @@
+# - Try to find OpenSync
+# Find OpenSync headers, libraries and the answer to all questions.
+#
+#  OPENSYNC_FOUND               True if OpenSync got found
+#  OPENSYNC_INCLUDE_DIRS         Location of OpenSync headers 
+#  OPENSYNC_LIBRARIES           List of libaries to use OpenSync
+#
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+# Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+# Take care about libopensync.pc settings
+INCLUDE( FindPkgConfig )
+
+IF ( OpenSync_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( OpenSync_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( OpenSync_FIND_REQUIRED )
+
+IF ( OPENSYNC_MIN_VERSION )
+	PKG_SEARCH_MODULE( OPENSYNC ${_pkgconfig_REQUIRED} libopensync1 >=${OPENSYNC_MIN_VERSION} )
+ELSE ( OPENSYNC_MIN_VERSION )
+	PKG_SEARCH_MODULE( OPENSYNC ${_pkgconfig_REQUIRED} libopensync1 )
+ENDIF ( OPENSYNC_MIN_VERSION )
+
+FIND_PROGRAM( PKGCONFIG_EXECUTABLE NAMES pkg-config )
+
+IF ( PKGCONFIG_EXECUTABLE )
+	EXEC_PROGRAM( ${PKGCONFIG_EXECUTABLE} ARGS libopensync1 --variable=datadir OUTPUT_VARIABLE _opensync_data_DIR )
+	STRING( REGEX REPLACE "[\r\n]" " " _opensync_data_DIR "${_opensync_data_DIR}"  )
+ENDIF ( PKGCONFIG_EXECUTABLE )
+
+FIND_PATH( OPENSYNC_CMAKE_MODULES "OpenSyncInternal.cmake" PATHS "${_opensync_data_DIR}" PATH_SUFFIXES "cmake/modules" NO_DEFAULT_PATH) 
+FIND_PATH( OPENSYNC_CMAKE_MODULES "OpenSyncInternal.cmake" PATH_SUFFIXES "cmake/modules" ) 
+
+IF ( OPENSYNC_CMAKE_MODULES )
+	SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${OPENSYNC_CMAKE_MODULES}" )
+ELSE ( OPENSYNC_CMAKE_MODULES )
+	IF ( OpenSync_FIND_REQUIRED )
+		MESSAGE( FATAL_ERROR "OpenSync cmake modules not found. Have you installed opensync core or did you set your PKG_CONFIG_PATH if installing in a non system directory ?" )
+	ENDIF ( OpenSync_FIND_REQUIRED )
+ENDIF ( OPENSYNC_CMAKE_MODULES )
+
+
+# Look for OpenSync include dir and libraries without pkg-config 
+IF( NOT OPENSYNC_FOUND AND NOT PKG_CONFIG_FOUND )
+	# Fallback if pkg-config doesn't exist
+	FIND_PATH( OPENSYNC_INCLUDE_DIRS opensync/opensync.h PATH_SUFFIXES libopensync libopensync1
+			PATHS
+			/opt/local/include/
+			/sw/include/
+			/usr/local/include/
+			/usr/include/ )
+
+	FIND_LIBRARY( OPENSYNC_LIBRARIES opensync
+			PATHS
+			/opt/local/lib
+			/sw/lib
+			/usr/lib
+			/usr/local/lib
+			/usr/lib64
+			/usr/local/lib64
+			/opt/lib64 )
+
+	# Report results
+	IF ( OPENSYNC_LIBRARIES AND OPENSYNC_INCLUDE_DIRS )	
+		SET( OPENSYNC_FOUND 1 )
+		IF ( NOT OpenSync_FIND_QUIETLY )
+			MESSAGE( STATUS "Found OpenSync: ${OPENSYNC_LIBRARIES}" )
+		ENDIF ( NOT OpenSync_FIND_QUIETLY )
+	ELSE ( OPENSYNC_LIBRARIES AND OPENSYNC_INCLUDE_DIRS )	
+		IF ( OpenSync_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find OpenSync" )
+		ELSE ( OpenSync_FIND_REQUIRED )
+			IF ( NOT OpenSync_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find OpenSync" )	
+			ENDIF ( NOT OpenSync_FIND_QUIETLY )
+		ENDIF ( OpenSync_FIND_REQUIRED )
+	ENDIF ( OPENSYNC_LIBRARIES AND OPENSYNC_INCLUDE_DIRS )	
+ENDIF( NOT OPENSYNC_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( OPENSYNC_LIBRARIES OPENSYNC_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindPilotLink.cmake b/cmake/modules/FindPilotLink.cmake
new file mode 100644
index 0000000..efbf105
--- /dev/null
+++ b/cmake/modules/FindPilotLink.cmake
@@ -0,0 +1,55 @@
+# - Try to find PilotLink
+# Find PilotLink headers, libraries and the answer to all questions.
+#
+#  PILOTLINK_FOUND               True if PilotLink got found
+#  PILOTLINK_INCLUDE_DIRS        Location of PilotLink headers 
+#  PILOTLINK_LIBRARIES           List of libaries to use PilotLink
+#  PILOTLINK_DEFINITIONS         Definitions to compile PilotLink 
+#
+#  Copyright (c) 2007 Daniel Gollub 
+#  Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( PilotLink_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( PilotLink_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( PilotLink_FIND_REQUIRED )
+
+IF ( PILOTLINK_MIN_VERSION )
+	PKG_SEARCH_MODULE( PILOTLINK ${_pkgconfig_REQUIRED} pilot-link>=${PILOTLINK_MIN_VERSION} )
+ELSE ( PILOTLINK_MIN_VERSION )
+	PKG_SEARCH_MODULE( PILOTLINK ${_pkgconfig_REQUIRED} pilot-link )
+ENDIF ( PILOTLINK_MIN_VERSION )
+
+
+IF( NOT PILOTLINK_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( PILOTLINK_INCLUDE_DIRS pilot-link )
+	FIND_LIBRARY( PILOTLINK_LIBRARIES pisock)
+
+	# Report results
+	IF ( PILOTLINK_LIBRARIES AND PILOTLINK_INCLUDE_DIRS )	
+		SET( PILOTLINK_FOUND 1 )
+		IF ( NOT PilotLink_FIND_QUIETLY )
+			MESSAGE( STATUS "Found PilotLink: ${PILOTLINK_LIBRARIES}" )
+		ENDIF ( NOT PilotLink_FIND_QUIETLY )
+	ELSE ( PILOTLINK_LIBRARIES AND PILOTLINK_INCLUDE_DIRS )	
+		IF ( PilotLink_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find PilotLink" )
+		ELSE ( PilotLink_FIND_REQUIRED )
+			IF ( NOT PilotLink_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find PilotLink" )	
+			ENDIF ( NOT PilotLink_FIND_QUIETLY )
+		ENDIF ( PilotLink_FIND_REQUIRED )
+	ENDIF ( PILOTLINK_LIBRARIES AND PILOTLINK_INCLUDE_DIRS )	
+ENDIF( NOT PILOTLINK_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( PILOTLINK_LIBRARIES PILOTLINK_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindPkgConfig.cmake b/cmake/modules/FindPkgConfig.cmake
new file mode 100644
index 0000000..979a3d9
--- /dev/null
+++ b/cmake/modules/FindPkgConfig.cmake
@@ -0,0 +1,373 @@
+# - a pkg-config module for CMake
+#
+# Usage:
+#   pkg_check_modules( [REQUIRED]  []*)
+#     checks for all the given modules
+#
+#   pkg_search_module( [REQUIRED]  []*)
+#     checks for given modules and uses the first working one
+#
+# When the 'REQUIRED' argument was set, macros will fail with an error
+# when module(s) could not be found
+#
+# It sets the following variables:
+#   PKG_CONFIG_FOUND         ... true iff pkg-config works on the system
+#   PKG_CONFIG_EXECUTABLE    ... pathname of the pkg-config program
+#   _FOUND           ... set to 1 iff module(s) exist
+#
+# For the following variables two sets of values exist; first one is the
+# common one and has the given PREFIX. The second set contains flags
+# which are given out when pkgconfig was called with the '--static'
+# option.
+#   _LIBRARIES      ... only the libraries (w/o the '-l')
+#   _LIBRARY_DIRS   ... the paths of the libraries (w/o the '-L')
+#   _LDFLAGS        ... all required linker flags
+#   _LDFLAGS_OTHERS ... all other linker flags
+#   _INCLUDE_DIRS   ... the '-I' preprocessor flags (w/o the '-I')
+#   _CFLAGS         ... all required cflags
+#   _CFLAGS_OTHERS  ... the other compiler flags
+#
+#    =         for common case
+#    = _STATIC for static linking
+#
+# There are some special variables whose prefix depends on the count
+# of given modules. When there is only one module,  stays
+# unchanged. When there are multiple modules, the prefix will be
+# changed to _:
+#   _VERSION    ... version of the module
+#   _PREFIX     ... prefix-directory of the module
+#   _INCLUDEDIR ... include-dir of the module
+#   _LIBDIR     ... lib-dir of the module
+#
+#    =   when |MODULES| == 1, else
+#    = _
+#
+# A  parameter can have the following formats:
+#   {MODNAME}            ... matches any version
+#   {MODNAME}>={VERSION} ... at least version  is required
+#   {MODNAME}={VERSION}  ... exactly version  is required
+#   {MODNAME}<={VERSION} ... modules must not be newer than 
+#
+# Examples
+#   pkg_check_modules (GLIB2   glib-2.0)
+#
+#   pkg_check_modules (GLIB2   glib-2.0>=2.10)
+#     requires at least version 2.10 of glib2 and defines e.g.
+#       GLIB2_VERSION=2.10.3
+#
+#   pkg_check_modules (FOO     glib-2.0>=2.10 gtk+-2.0)
+#     requires both glib2 and gtk2, and defines e.g.
+#       FOO_glib-2.0_VERSION=2.10.3
+#       FOO_gtk+-2.0_VERSION=2.8.20
+#
+#   pkg_check_modules (XRENDER REQUIRED xrender)
+#     defines e.g.:
+#       XRENDER_LIBRARIES=Xrender;X11
+#       XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp
+#
+#   pkg_search_module (BAR     libxml-2.0 libxml2 libxml>=2)
+
+
+# Copyright (C) 2006 Enrico Scholz 
+#
+# Redistribution and use, with or without modification, are permitted
+# provided that the following conditions are met:
+# 
+#    1. Redistributions must retain the above copyright notice, this
+#       list of conditions and the following disclaimer.
+#    2. The name of the author may not be used to endorse or promote
+#       products derived from this software without specific prior
+#       written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### Common stuff ####
+set(PKG_CONFIG_VERSION 1)
+set(PKG_CONFIG_FOUND   0)
+
+IF ( PkgConfig_FIND_REQUIRED )
+	SET( PKGCONFIG_REQUIRED "REQUIRED" )
+ELSE( PkgConfig_FIND_REQUIRED )
+	SET( PKGCONFIG_REQUIRED "" )	
+ENDIF ( PkgConfig_FIND_REQUIRED )
+
+find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config DOC "pkg-config executable")
+mark_as_advanced(PKG_CONFIG_EXECUTABLE)
+
+if(PKG_CONFIG_EXECUTABLE)
+  set(PKG_CONFIG_FOUND 1)
+endif(PKG_CONFIG_EXECUTABLE)
+
+
+# Unsets the given variables
+macro(_pkgconfig_unset var)
+  set(${var} "" CACHE INTERNAL "")
+endmacro(_pkgconfig_unset)
+
+macro(_pkgconfig_set var value)
+  set(${var} ${value} CACHE INTERNAL "")
+endmacro(_pkgconfig_set)
+
+# Invokes pkgconfig, cleans up the result and sets variables
+macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp)
+  set(_pkgconfig_invoke_result)
+
+  execute_process(
+    COMMAND ${PKG_CONFIG_EXECUTABLE} ${ARGN} ${_pkglist}
+    OUTPUT_VARIABLE _pkgconfig_invoke_result
+    RESULT_VARIABLE _pkgconfig_failed)
+
+  if (_pkgconfig_failed)
+    set(_pkgconfig_${_varname} "")
+    _pkgconfig_unset(${_prefix}_${_varname})
+  else(_pkgconfig_failed)
+    string(REGEX REPLACE "[\r\n]"                  " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}")
+    string(REGEX REPLACE " +$"                     ""  _pkgconfig_invoke_result "${_pkgconfig_invoke_result}")
+
+    if (NOT ${_regexp} STREQUAL "")
+      string(REGEX REPLACE "${_regexp}" " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}")
+    endif(NOT ${_regexp} STREQUAL "")
+
+    separate_arguments(_pkgconfig_invoke_result)
+
+    #message(STATUS "  ${_varname} ... ${_pkgconfig_invoke_result}")
+    set(_pkgconfig_${_varname} ${_pkgconfig_invoke_result})
+    _pkgconfig_set(${_prefix}_${_varname} "${_pkgconfig_invoke_result}")
+  endif(_pkgconfig_failed)
+endmacro(_pkgconfig_invoke)
+
+# Invokes pkgconfig two times; once without '--static' and once with
+# '--static'
+macro(_pkgconfig_invoke_dyn _pkglist _prefix _varname cleanup_regexp)
+  _pkgconfig_invoke("${_pkglist}" ${_prefix}        ${_varname} "${cleanup_regexp}" ${ARGN})
+  _pkgconfig_invoke("${_pkglist}" ${_prefix} STATIC_${_varname} "${cleanup_regexp}" --static  ${ARGN})
+endmacro(_pkgconfig_invoke_dyn)
+
+# Splits given arguments into options and a package list
+macro(_pkgconfig_parse_options _result _is_req)
+  set(${_is_req} 0)
+  
+  foreach(_pkg ${ARGN})
+    if (_pkg STREQUAL "REQUIRED")
+      set(${_is_req} 1)
+    endif (_pkg STREQUAL "REQUIRED")
+  endforeach(_pkg ${ARGN})
+
+  set(${_result} ${ARGN})
+  list(REMOVE_ITEM ${_result} "REQUIRED")
+endmacro(_pkgconfig_parse_options)
+
+###
+macro(_pkg_check_modules_internal _is_required _is_silent _prefix)
+  _pkgconfig_unset(${_prefix}_FOUND)
+  _pkgconfig_unset(${_prefix}_VERSION)
+  _pkgconfig_unset(${_prefix}_PREFIX)
+  _pkgconfig_unset(${_prefix}_INCLUDEDIR)
+  _pkgconfig_unset(${_prefix}_LIBDIR)
+  _pkgconfig_unset(${_prefix}_LIBS)
+  _pkgconfig_unset(${_prefix}_LIBS_L)
+  _pkgconfig_unset(${_prefix}_LIBS_PATHS)
+  _pkgconfig_unset(${_prefix}_LIBS_OTHER)
+  _pkgconfig_unset(${_prefix}_CFLAGS)
+  _pkgconfig_unset(${_prefix}_CFLAGS_I)
+  _pkgconfig_unset(${_prefix}_CFLAGS_OTHER)
+  _pkgconfig_unset(${_prefix}_STATIC_LIBDIR)
+  _pkgconfig_unset(${_prefix}_STATIC_LIBS)
+  _pkgconfig_unset(${_prefix}_STATIC_LIBS_L)
+  _pkgconfig_unset(${_prefix}_STATIC_LIBS_PATHS)
+  _pkgconfig_unset(${_prefix}_STATIC_LIBS_OTHER)
+  _pkgconfig_unset(${_prefix}_STATIC_CFLAGS)
+  _pkgconfig_unset(${_prefix}_STATIC_CFLAGS_I)
+  _pkgconfig_unset(${_prefix}_STATIC_CFLAGS_OTHER)
+
+  # create a better addressable variable of the modules and calculate its size
+  set(_pkg_check_modules_list ${ARGN})
+  list(LENGTH _pkg_check_modules_list _pkg_check_modules_cnt)
+
+  if(PKG_CONFIG_FOUND)
+    # give out status message telling checked module
+    if (NOT ${_is_silent})
+      if (_pkg_check_modules_cnt EQUAL 1)
+        message(STATUS "checking for module '${_pkg_check_modules_list}'")
+      else(_pkg_check_modules_cnt EQUAL 1)
+        message(STATUS "checking for modules '${_pkg_check_modules_list}'")
+      endif(_pkg_check_modules_cnt EQUAL 1)
+    endif(NOT ${_is_silent})
+    
+    set(_pkg_check_modules_packages)
+    set(_pkg_check_modules_failed)
+
+    # iterate through module list and check whether they exist and match the required version
+    foreach (_pkg_check_modules_pkg ${_pkg_check_modules_list})
+      set(_pkg_check_modules_exist_query)
+
+      # check whether version is given
+      if (_pkg_check_modules_pkg MATCHES ".*(>=|=|<=).*")
+        string(REGEX REPLACE "(.*[^><])(>=|=|<=)(.*)" "\\1" _pkg_check_modules_pkg_name "${_pkg_check_modules_pkg}")
+        string(REGEX REPLACE "(.*[^><])(>=|=|<=)(.*)" "\\2" _pkg_check_modules_pkg_op   "${_pkg_check_modules_pkg}")
+        string(REGEX REPLACE "(.*[^><])(>=|=|<=)(.*)" "\\3" _pkg_check_modules_pkg_ver  "${_pkg_check_modules_pkg}")
+      else(_pkg_check_modules_pkg MATCHES ".*(>=|=|<=).*")
+        set(_pkg_check_modules_pkg_name "${_pkg_check_modules_pkg}")
+        set(_pkg_check_modules_pkg_op)
+        set(_pkg_check_modules_pkg_ver)
+      endif(_pkg_check_modules_pkg MATCHES ".*(>=|=|<=).*")
+
+      # handle the operands
+      if (_pkg_check_modules_pkg_op STREQUAL ">=")
+        list(APPEND _pkg_check_modules_exist_query --atleast-version)
+      endif(_pkg_check_modules_pkg_op STREQUAL ">=")
+
+      if (_pkg_check_modules_pkg_op STREQUAL "=")
+        list(APPEND _pkg_check_modules_exist_query --exact-version)
+      endif(_pkg_check_modules_pkg_op STREQUAL "=")
+      
+      if (_pkg_check_modules_pkg_op STREQUAL "<=")
+        list(APPEND _pkg_check_modules_exist_query --max-version)
+      endif(_pkg_check_modules_pkg_op STREQUAL "<=")
+
+      # create the final query which is of the format:
+      # * --atleast-version  
+      # * --exact-version        
+      # * --max-version  
+      # * --exists 
+      if (_pkg_check_modules_pkg_op)
+        list(APPEND _pkg_check_modules_exist_query "${_pkg_check_modules_pkg_ver}")
+      else(_pkg_check_modules_pkg_op)
+        list(APPEND _pkg_check_modules_exist_query --exists)
+      endif(_pkg_check_modules_pkg_op)
+
+      _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_VERSION)
+      _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_PREFIX)
+      _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_INCLUDEDIR)
+      _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_LIBDIR)
+
+      list(APPEND _pkg_check_modules_exist_query "${_pkg_check_modules_pkg_name}")
+      list(APPEND _pkg_check_modules_packages    "${_pkg_check_modules_pkg_name}")
+
+      # execute the query
+      execute_process(
+        COMMAND ${PKG_CONFIG_EXECUTABLE} ${_pkg_check_modules_exist_query}
+        RESULT_VARIABLE _pkgconfig_retval)
+
+      # evaluate result and tell failures
+      if (_pkgconfig_retval)
+        if(NOT ${_is_silent})
+          message(STATUS "  package '${_pkg_check_modules_pkg}' not found")
+        endif(NOT ${_is_silent})
+
+        set(_pkg_check_modules_failed 1)
+      endif(_pkgconfig_retval)
+    endforeach(_pkg_check_modules_pkg)
+
+    if(_pkg_check_modules_failed)
+      # fail when requested
+      if (${_is_required})
+        message(SEND_ERROR "A required package was not found")
+      endif (${_is_required})
+    else(_pkg_check_modules_failed)
+      # when we are here, we checked whether requested modules
+      # exist. Now, go through them and set variables
+      
+      _pkgconfig_set(${_prefix}_FOUND 1)
+      list(LENGTH _pkg_check_modules_packages pkg_count)
+
+      # iterate through all modules again and set individual variables
+      foreach (_pkg_check_modules_pkg ${_pkg_check_modules_packages})
+        # handle case when there is only one package required
+        if (pkg_count EQUAL 1)
+          set(_pkg_check_prefix "${_prefix}")
+        else(pkg_count EQUAL 1)
+          set(_pkg_check_prefix "${_prefix}_${_pkg_check_modules_pkg}")
+        endif(pkg_count EQUAL 1)
+        
+        _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" VERSION    ""   --modversion )
+        _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" PREFIX     ""   --variable=prefix )
+        _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" INCLUDEDIR ""   --variable=includedir )
+        _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" LIBDIR     ""   --variable=libdir )
+
+        message(STATUS "  found ${_pkg_check_modules_pkg}, version ${_pkgconfig_VERSION}")
+      endforeach(_pkg_check_modules_pkg)
+
+      # set variables which are combined for multiple modules
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARIES           "(^| )-l" --libs-only-l )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARY_DIRS        "(^| )-L" --libs-only-L )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS             ""        --libs )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS_OTHER       ""        --libs-only-other )
+
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" INCLUDE_DIRS        "(^| )-I" --cflags-only-I )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS              ""        --cflags )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS_OTHER        ""        --cflags-only-other )
+    endif(_pkg_check_modules_failed)
+  else(PKG_CONFIG_FOUND)
+    if (PKGCONFIG_REQUIRED AND ${_is_required})
+      message(SEND_ERROR "pkg-config tool not found")
+    endif (PKGCONFIG_REQUIRED AND ${_is_required})
+  endif(PKG_CONFIG_FOUND)
+endmacro(_pkg_check_modules_internal)
+
+###
+### User visible macros start here
+###
+
+###
+macro(pkg_check_modules _prefix _module0)
+  # check cached value
+  if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION})
+    _pkgconfig_parse_options   (_pkg_modules _pkg_is_required "${_module0}" ${ARGN})
+    _pkg_check_modules_internal("${_pkg_is_required}" 0 "${_prefix}" ${_pkg_modules})
+
+    _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
+  endif(NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION})
+endmacro(pkg_check_modules)
+
+###
+macro(pkg_search_module _prefix _module0)
+  if(PKG_CONFIG_FOUND)
+      # check cached value
+      if ( NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND )
+        set(_pkg_modules_found 0)
+        _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required "${_module0}" ${ARGN})
+    
+        message(STATUS "checking for one of the modules '${_pkg_modules_alt}'")
+    
+        # iterate through all modules and stop at the first working one.
+        foreach(_pkg_alt ${_pkg_modules_alt})
+          if(NOT _pkg_modules_found)
+            _pkg_check_modules_internal(0 1 "${_prefix}" "${_pkg_alt}")
+          endif(NOT _pkg_modules_found)
+    
+          if (${_prefix}_FOUND)
+            set(_pkg_modules_found 1)
+          endif(${_prefix}_FOUND)
+        endforeach(_pkg_alt)
+    
+        if (NOT ${_prefix}_FOUND)
+          if(${_pkg_is_required})
+            message(SEND_ERROR "None of the required '${_pkg_modules_alt}' found")
+          endif(${_pkg_is_required})
+        endif(NOT ${_prefix}_FOUND)
+        
+        _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
+      endif(NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND )
+  else(PKG_CONFIG_FOUND)
+    if (PKGCONFIG_REQUIRED)
+      message(SEND_ERROR "pkg-config tool not found")
+    endif (PKGCONFIG_REQUIRED)
+  endif(PKG_CONFIG_FOUND)
+  
+endmacro(pkg_search_module)
+
+### Local Variables:
+### mode: cmake
+### End:
diff --git a/cmake/modules/FindPythonLibs.cmake b/cmake/modules/FindPythonLibs.cmake
new file mode 100644
index 0000000..6a1061d
--- /dev/null
+++ b/cmake/modules/FindPythonLibs.cmake
@@ -0,0 +1,160 @@
+# - Find python libraries
+# This module finds if Python is installed and determines where the
+# include files and libraries are. It also determines what the name of
+# the library is. This code sets the following variables:
+#
+#  PYTHON_LIBRARIES     = path to the python library
+#  PYTHON_INCLUDE_PATH  = path to where Python.h is found
+#  PYTHON_DEBUG_LIBRARIES = path to the debug library
+#  PYTHON_VERSION = version of python library
+#
+#  The user can set this variable to choose their preferred python 
+#  version to be found:
+#
+#  PREFERRED_PYTHON_VERSION = preferred version of the python library 
+
+INCLUDE(CMakeFindFrameworks)
+
+IF(WIN32)
+  FIND_LIBRARY(PYTHON_DEBUG_LIBRARY
+    NAMES python26_d python25_d python24_d python23_d python22_d python21_d python20_d python
+    PATHS
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]/libs/Debug
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]/libs/Debug
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]/libs/Debug
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]/libs/Debug
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.2\\InstallPath]/libs/Debug
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.2\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.1\\InstallPath]/libs/Debug
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.1\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.0\\InstallPath]/libs/Debug
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.0\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\1.6\\InstallPath]/libs/Debug
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\1.6\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\1.5\\InstallPath]/libs/Debug
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\1.5\\InstallPath]/libs
+  )
+ENDIF(WIN32)
+
+FIND_LIBRARY(PYTHON_LIBRARY ${PREFERRED_PYTHON_VERSION}
+  NAMES python26 python2.6
+        python25 python2.5
+        python24 python2.4
+        python23 python2.3
+        python22 python2.2
+        python21 python2.1
+        python20 python2.0
+        python16 python1.6
+        python15 python1.5
+
+  PATHS
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.2\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.1\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.0\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\1.6\\InstallPath]/libs
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\1.5\\InstallPath]/libs
+
+  PATH_SUFFIXES
+    python2.6/config
+    python2.5/config
+    python2.4/config
+    python2.3/config
+    python2.2/config
+    python2.1/config
+    python2.0/config
+    python1.6/config
+    python1.5/config
+)
+IF(PYTHON_LIBRARY)
+message(STATUS "Found Python: ${PYTHON_LIBRARY}")
+ENDIF(PYTHON_LIBRARY)
+
+# Search for the python framework on Apple.
+CMAKE_FIND_FRAMEWORKS(Python)
+SET(PYTHON_FRAMEWORK_INCLUDES)
+IF(Python_FRAMEWORKS)
+  IF(NOT PYTHON_INCLUDE_PATH)
+    FOREACH(version 2.6 2.5 2.4 2.3 2.2 2.1 2.0 1.6 1.5)
+      FOREACH(dir ${Python_FRAMEWORKS})
+        SET(PYTHON_FRAMEWORK_INCLUDES ${PYTHON_FRAMEWORK_INCLUDES}
+          ${dir}/Versions/${version}/include/python${version})
+      ENDFOREACH(dir)
+    ENDFOREACH(version)
+  ENDIF(NOT PYTHON_INCLUDE_PATH)
+ENDIF(Python_FRAMEWORKS)
+
+FIND_PATH(PYTHON_INCLUDE_PATH
+  NAMES Python.h
+
+  PATHS
+    ${PYTHON_FRAMEWORK_INCLUDES}
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]/include
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]/include
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]/include
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]/include
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.2\\InstallPath]/include
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.1\\InstallPath]/include
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.0\\InstallPath]/include
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\1.6\\InstallPath]/include
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\1.5\\InstallPath]/include
+
+  PATH_SUFFIXES
+    ${PREFERRED_PYTHON_VERSION}
+    python2.6
+    python2.5
+    python2.4
+    python2.3
+    python2.2
+    python2.1
+    python2.0
+    python1.6
+    python1.5
+)
+
+IF (WIN32)
+  MARK_AS_ADVANCED(
+    PYTHON_DEBUG_LIBRARY
+    PYTHON_LIBRARY
+    PYTHON_INCLUDE_PATH
+  )
+ENDIF(WIN32)
+
+
+FIND_PROGRAM( PYTHON_EXECUTABLE NAMES ${PREFERRED_PYTHON_VERSION} python )
+
+IF ( PYTHON_EXECUTABLE )
+	EXEC_PROGRAM( ${PYTHON_EXECUTABLE} ARGS "-c \"import sys; print sys.version[:3]\"" OUTPUT_VARIABLE PYTHON_VERSION )
+	STRING( REGEX REPLACE "[\r\n]" " " PYTHON_VERSION "${PYTHON_VERSION}"  )
+ENDIF ( PYTHON_EXECUTABLE )
+
+# Python Should be built and installed as a Framework on OSX
+IF(Python_FRAMEWORKS)
+  # If a framework has been selected for the include path,
+  # make sure "-framework" is used to link it.
+  IF("${PYTHON_INCLUDE_PATH}" MATCHES "Python\\.framework")
+    SET(PYTHON_LIBRARY "")
+    SET(PYTHON_DEBUG_LIBRARY "")
+  ENDIF("${PYTHON_INCLUDE_PATH}" MATCHES "Python\\.framework")
+  IF(NOT PYTHON_LIBRARY)
+    SET (PYTHON_LIBRARY "-framework Python" CACHE FILEPATH "Python Framework" FORCE)
+  ENDIF(NOT PYTHON_LIBRARY)
+  IF(NOT PYTHON_DEBUG_LIBRARY)
+    SET (PYTHON_DEBUG_LIBRARY "-framework Python" CACHE FILEPATH "Python Framework" FORCE)
+  ENDIF(NOT PYTHON_DEBUG_LIBRARY)
+ENDIF(Python_FRAMEWORKS)
+
+# We use PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the cache entries
+# because they are meant to specify the location of a single library.
+# We now set the variables listed by the documentation for this
+# module.
+SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
+SET(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}")
+
diff --git a/cmake/modules/FindQt4.cmake b/cmake/modules/FindQt4.cmake
new file mode 100644
index 0000000..55c44df
--- /dev/null
+++ b/cmake/modules/FindQt4.cmake
@@ -0,0 +1,1468 @@
+# - Find QT 4
+# This module can be used to find Qt4.
+# The most important issue is that the Qt4 qmake is available via the system path.
+# This qmake is then used to detect basically everything else.
+# This module defines a number of key variables and macros. 
+# First is QT_USE_FILE which is the path to a CMake file that can be included 
+# to compile Qt 4 applications and libraries.  By default, the QtCore and QtGui 
+# libraries are loaded. This behavior can be changed by setting one or more 
+# of the following variables to true before doing INCLUDE(${QT_USE_FILE}):
+#                    QT_DONT_USE_QTCORE
+#                    QT_DONT_USE_QTGUI
+#                    QT_USE_QT3SUPPORT
+#                    QT_USE_QTASSISTANT
+#                    QT_USE_QTDESIGNER
+#                    QT_USE_QTMOTIF
+#                    QT_USE_QTMAIN
+#                    QT_USE_QTNETWORK
+#                    QT_USE_QTNSPLUGIN
+#                    QT_USE_QTOPENGL
+#                    QT_USE_QTSQL
+#                    QT_USE_QTXML
+#                    QT_USE_QTSVG
+#                    QT_USE_QTTEST
+#                    QT_USE_QTUITOOLS
+#                    QT_USE_QTDBUS
+#                    QT_USE_QTSCRIPT
+#                    QT_USE_QTASSISTANTCLIENT
+#                    QT_USE_QTHELP
+#                    QT_USE_QTWEBKIT
+#                    QT_USE_QTXMLPATTERNS
+#                    QT_USE_PHONON
+#
+# The file pointed to by QT_USE_FILE will set up your compile environment
+# by adding include directories, preprocessor defines, and populate a
+# QT_LIBRARIES variable containing all the Qt libraries and their dependencies.
+# Add the QT_LIBRARIES variable to your TARGET_LINK_LIBRARIES.
+#
+# Typical usage could be something like:
+#   FIND_PACKAGE(Qt4)
+#   SET(QT_USE_QTXML 1)
+#   INCLUDE(${QT_USE_FILE})
+#   ADD_EXECUTABLE(myexe main.cpp)
+#   TARGET_LINK_LIBRARIES(myexe ${QT_LIBRARIES})
+#
+#
+# There are also some files that need processing by some Qt tools such as moc
+# and uic.  Listed below are macros that may be used to process those files.
+#  
+#  macro QT4_WRAP_CPP(outfiles inputfile ... OPTIONS ...)
+#        create moc code from a list of files containing Qt class with
+#        the Q_OBJECT declaration.  Options may be given to moc, such as those found
+#        when executing "moc -help"
+#
+#  macro QT4_WRAP_UI(outfiles inputfile ... OPTIONS ...)
+#        create code from a list of Qt designer ui files.
+#        Options may be given to uic, such as those found
+#        when executing "uic -help"
+#
+#  macro QT4_ADD_RESOURCES(outfiles inputfile ... OPTIONS ...)
+#        create code from a list of Qt resource files.
+#        Options may be given to rcc, such as those found
+#        when executing "rcc -help"
+#
+#  macro QT4_GENERATE_MOC(inputfile outputfile )
+#        creates a rule to run moc on infile and create outfile.
+#        Use this if for some reason QT4_WRAP_CPP() isn't appropriate, e.g.
+#        because you need a custom filename for the moc file or something similar.
+#
+#  macro QT4_AUTOMOC(sourcefile1 sourcefile2 ... )
+#        This macro is still experimental.
+#        It can be used to have moc automatically handled.
+#        So if you have the files foo.h and foo.cpp, and in foo.h a 
+#        a class uses the Q_OBJECT macro, moc has to run on it. If you don't
+#        want to use QT4_WRAP_CPP() (which is reliable and mature), you can insert
+#        #include "foo.moc"
+#        in foo.cpp and then give foo.cpp as argument to QT4_AUTOMOC(). This will the
+#        scan all listed files at cmake-time for such included moc files and if it finds
+#        them cause a rule to be generated to run moc at build time on the 
+#        accompanying header file foo.h.
+#        If a source file has the SKIP_AUTOMOC property set it will be ignored by this macro.
+#
+#  macro QT4_ADD_DBUS_INTERFACE(outfiles interface basename)
+#        create a the interface header and implementation files with the 
+#        given basename from the given interface xml file and add it to 
+#        the list of sources.
+#        To disable generating a namespace header, set the source file property 
+#        NO_NAMESPACE to TRUE on the interface file.
+#
+#  macro QT4_ADD_DBUS_INTERFACES(outfiles inputfile ... )
+#        create the interface header and implementation files 
+#        for all listed interface xml files
+#        the name will be automatically determined from the name of the xml file
+#        To disable generating namespace headers, set the source file property 
+#        NO_NAMESPACE to TRUE for these inputfiles.
+#
+#  macro QT4_ADD_DBUS_ADAPTOR(outfiles xmlfile parentheader parentclassname [basename] [classname])
+#        create a dbus adaptor (header and implementation file) from the xml file
+#        describing the interface, and add it to the list of sources. The adaptor
+#        forwards the calls to a parent class, defined in parentheader and named
+#        parentclassname. The name of the generated files will be
+#        adaptor.{cpp,h} where basename defaults to the basename of the xml file.
+#        If  is provided, then it will be used as the classname of the
+#        adaptor itself.
+#
+#  macro QT4_GENERATE_DBUS_INTERFACE( header [interfacename] OPTIONS ...)
+#        generate the xml interface file from the given header.
+#        If the optional argument interfacename is omitted, the name of the 
+#        interface file is constructed from the basename of the header with
+#        the suffix .xml appended.
+#        Options may be given to qdbuscpp2xml, such as those found when executing "qdbuscpp2xml --help"
+#
+#  QT_FOUND         If false, don't try to use Qt.
+#  QT4_FOUND        If false, don't try to use Qt 4.
+#
+#  QT_QTCORE_FOUND        True if QtCore was found.
+#  QT_QTGUI_FOUND         True if QtGui was found.
+#  QT_QT3SUPPORT_FOUND    True if Qt3Support was found.
+#  QT_QTASSISTANT_FOUND   True if QtAssistant was found.
+#  QT_QTDBUS_FOUND        True if QtDBus was found.
+#  QT_QTDESIGNER_FOUND    True if QtDesigner was found.
+#  QT_QTDESIGNERCOMPONENTS True if QtDesignerComponents was found.
+#  QT_QTMOTIF_FOUND       True if QtMotif was found.
+#  QT_QTNETWORK_FOUND     True if QtNetwork was found.
+#  QT_QTNSPLUGIN_FOUND    True if QtNsPlugin was found.
+#  QT_QTOPENGL_FOUND      True if QtOpenGL was found.
+#  QT_QTSQL_FOUND         True if QtSql was found.
+#  QT_QTXML_FOUND         True if QtXml was found.
+#  QT_QTSVG_FOUND         True if QtSvg was found.
+#  QT_QTSCRIPT_FOUND      True if QtScript was found.
+#  QT_QTTEST_FOUND        True if QtTest was found.
+#  QT_QTUITOOLS_FOUND     True if QtUiTools was found.
+#  QT_QTASSISTANTCLIENT_FOUND         True if QtAssistantClient was found.
+#  QT_QTHELP_FOUND      True if QtHelp was found.
+#  QT_QTWEBKIT_FOUND        True if QtWebKit was found.
+#  QT_QTXMLPATTERNS_FOUND   True if QtXmlPatterns was found.
+#  QT_PHONON_FOUND          True if phonon was found.
+#
+#
+#  QT_DEFINITIONS   Definitions to use when compiling code that uses Qt.
+#                   You do not need to use this if you include QT_USE_FILE.
+#                   The QT_USE_FILE will also define QT_DEBUG and QT_NO_DEBUG
+#                   to fit your current build type.  Those are not contained
+#                   in QT_DEFINITIONS.
+#                  
+#  QT_INCLUDES      List of paths to all include directories of 
+#                   Qt4 QT_INCLUDE_DIR and QT_QTCORE_INCLUDE_DIR are
+#                   always in this variable even if NOTFOUND,
+#                   all other INCLUDE_DIRS are
+#                   only added if they are found.
+#                   You do not need to use this if you include QT_USE_FILE.
+#   
+#
+#  Include directories for the Qt modules are listed here.
+#  You do not need to use these variables if you include QT_USE_FILE.
+#
+#  QT_INCLUDE_DIR              Path to "include" of Qt4
+#  QT_QT_INCLUDE_DIR           Path to "include/Qt" 
+#  QT_QT3SUPPORT_INCLUDE_DIR   Path to "include/Qt3Support" 
+#  QT_QTASSISTANT_INCLUDE_DIR  Path to "include/QtAssistant" 
+#  QT_QTCORE_INCLUDE_DIR       Path to "include/QtCore"         
+#  QT_QTDESIGNER_INCLUDE_DIR   Path to "include/QtDesigner" 
+#  QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR   Path to "include/QtDesigner"
+#  QT_QTDBUS_INCLUDE_DIR       Path to "include/QtDBus" 
+#  QT_QTGUI_INCLUDE_DIR        Path to "include/QtGui" 
+#  QT_QTMOTIF_INCLUDE_DIR      Path to "include/QtMotif" 
+#  QT_QTNETWORK_INCLUDE_DIR    Path to "include/QtNetwork" 
+#  QT_QTNSPLUGIN_INCLUDE_DIR   Path to "include/QtNsPlugin" 
+#  QT_QTOPENGL_INCLUDE_DIR     Path to "include/QtOpenGL" 
+#  QT_QTSQL_INCLUDE_DIR        Path to "include/QtSql" 
+#  QT_QTXML_INCLUDE_DIR        Path to "include/QtXml" 
+#  QT_QTSVG_INCLUDE_DIR        Path to "include/QtSvg"
+#  QT_QTSCRIPT_INCLUDE_DIR     Path to "include/QtScript"
+#  QT_QTTEST_INCLUDE_DIR       Path to "include/QtTest"
+#  QT_QTASSISTANTCLIENT_INCLUDE_DIR       Path to "include/QtAssistant"
+#  QT_QTHELP_INCLUDE_DIR       Path to "include/QtHelp"
+#  QT_QTWEBKIT_INCLUDE_DIR     Path to "include/QtWebKit"
+#  QT_QTXMLPATTERNS_INCLUDE_DIR  Path to "include/QtXmlPatterns"
+#  QT_PHONON_INCLUDE_DIR       Path to "include/phonon"
+#                            
+#  QT_LIBRARY_DIR              Path to "lib" of Qt4
+# 
+#  QT_PLUGINS_DIR              Path to "plugins" for Qt4
+#                            
+# For every library of Qt, a QT_QTFOO_LIBRARY variable is defined, with the full path to the library.
+#
+# So there are the following variables:
+# The Qt3Support library:     QT_QT3SUPPORT_LIBRARY
+#
+# The QtAssistant library:    QT_QTASSISTANT_LIBRARY
+#
+# The QtCore library:         QT_QTCORE_LIBRARY
+#
+# The QtDBus library:         QT_QTDBUS_LIBRARY
+#
+# The QtDesigner library:     QT_QTDESIGNER_LIBRARY
+#
+# The QtDesignerComponents library:     QT_QTDESIGNERCOMPONENTS_LIBRARY
+#
+# The QtGui library:          QT_QTGUI_LIBRARY
+#
+# The QtMotif library:        QT_QTMOTIF_LIBRARY
+#
+# The QtNetwork library:      QT_QTNETWORK_LIBRARY
+#
+# The QtNsPLugin library:     QT_QTNSPLUGIN_LIBRARY
+#
+# The QtOpenGL library:       QT_QTOPENGL_LIBRARY
+#
+# The QtSql library:          QT_QTSQL_LIBRARY
+#
+# The QtXml library:          QT_QTXML_LIBRARY
+#
+# The QtSvg library:          QT_QTSVG_LIBRARY
+#
+# The QtScript library:       QT_QTSCRIPT_LIBRARY
+#
+# The QtTest library:         QT_QTTEST_LIBRARY
+#
+# The qtmain library for Windows QT_QTMAIN_LIBRARY
+#
+# The QtUiTools library:      QT_QTUITOOLS_LIBRARY
+#
+# The QtAssistantClient library:  QT_QTASSISTANTCLIENT_LIBRARY
+#
+# The QtHelp library:             QT_QTHELP_LIBRARY
+#
+# The QtWebKit library:           QT_QTWEBKIT_LIBRARY
+#
+# The QtXmlPatterns library:      QT_QTXMLPATTERNS_LIBRARY
+#
+# The Phonon library:             QT_PHONON_LIBRARY
+#  
+# also defined, but NOT for general use are
+#  QT_MOC_EXECUTABLE          Where to find the moc tool.
+#  QT_UIC_EXECUTABLE          Where to find the uic tool.
+#  QT_UIC3_EXECUTABLE         Where to find the uic3 tool.
+#  QT_RCC_EXECUTABLE          Where to find the rcc tool
+#  QT_DBUSCPP2XML_EXECUTABLE  Where to find the qdbuscpp2xml tool.
+#  QT_DBUSXML2CPP_EXECUTABLE  Where to find the qdbusxml2cpp tool.
+#  QT_LUPDATE_EXECUTABLE      Where to find the lupdate tool.
+#  QT_LRELEASE_EXECUTABLE     Where to find the lrelease tool.
+#  
+#  QT_DOC_DIR                 Path to "doc" of Qt4
+#  QT_MKSPECS_DIR             Path to "mkspecs" of Qt4
+#
+#
+# These are around for backwards compatibility 
+# they will be set
+#  QT_WRAP_CPP  Set true if QT_MOC_EXECUTABLE is found
+#  QT_WRAP_UI   Set true if QT_UIC_EXECUTABLE is found
+#  
+# These variables do _NOT_ have any effect anymore (compared to FindQt.cmake)
+#  QT_MT_REQUIRED         Qt4 is now always multithreaded
+#  
+# These variables are set to "" Because Qt structure changed 
+# (They make no sense in Qt4)
+#  QT_QT_LIBRARY        Qt-Library is now split
+
+# Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
+# See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+if (QT4_QMAKE_FOUND)
+   # Check already done in this cmake run, nothing more to do
+
+else (QT4_QMAKE_FOUND)
+
+# check that QT_NO_DEBUG is defined for release configurations
+MACRO(QT_CHECK_FLAG_EXISTS FLAG VAR DOC)
+  IF(NOT ${VAR} MATCHES "${FLAG}")
+    SET(${VAR} "${${VAR}} ${FLAG}" 
+      CACHE STRING "Flags used by the compiler during ${DOC} builds." FORCE)
+  ENDIF(NOT ${VAR} MATCHES "${FLAG}")
+ENDMACRO(QT_CHECK_FLAG_EXISTS FLAG VAR)
+QT_CHECK_FLAG_EXISTS(-DQT_NO_DEBUG CMAKE_CXX_FLAGS_RELWITHDEBINFO "Release with Debug Info")
+QT_CHECK_FLAG_EXISTS(-DQT_NO_DEBUG CMAKE_CXX_FLAGS_RELEASE "release")
+QT_CHECK_FLAG_EXISTS(-DQT_NO_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL "release minsize")
+
+INCLUDE(CheckSymbolExists)
+INCLUDE(MacroAddFileDependencies)
+INCLUDE(MacroPushRequiredVars)
+
+SET(QT_USE_FILE ${CMAKE_ROOT}/Modules/UseQt4.cmake)
+
+SET( QT_DEFINITIONS "")
+
+IF (WIN32)
+  SET(QT_DEFINITIONS -DQT_DLL)
+ENDIF(WIN32)
+
+SET(QT4_INSTALLED_VERSION_TOO_OLD FALSE)
+
+#  macro for asking qmake to process pro files
+MACRO(QT_QUERY_QMAKE outvar invar)
+  FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake/tmp.pro
+    "message(CMAKE_MESSAGE<$$${invar}>)")
+
+  # Invoke qmake with the tmp.pro program to get the desired
+  # information.  Use the same variable for both stdout and stderr
+  # to make sure we get the output on all platforms.
+  EXECUTE_PROCESS(COMMAND ${QT_QMAKE_EXECUTABLE}
+    WORKING_DIRECTORY  
+    ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake
+    OUTPUT_VARIABLE _qmake_query_output
+    RESULT_VARIABLE _qmake_result
+    ERROR_VARIABLE _qmake_query_output )
+  
+  FILE(REMOVE_RECURSE 
+    "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake")
+
+  IF(_qmake_result)
+    MESSAGE(WARNING " querying qmake for ${invar}.  qmake reported:\n${_qmake_query_output}")
+  ELSE(_qmake_result)
+    STRING(REGEX REPLACE ".*CMAKE_MESSAGE<([^>]*).*" "\\1" ${outvar} "${_qmake_query_output}")
+  ENDIF(_qmake_result)
+
+ENDMACRO(QT_QUERY_QMAKE)
+
+GET_FILENAME_COMPONENT(qt_install_version "[HKEY_CURRENT_USER\\Software\\trolltech\\Versions;DefaultQtVersion]" NAME)
+# check for qmake
+FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake qmake4 qmake-qt4 PATHS
+  "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/bin"
+  "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/bin"
+  "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\${qt_install_version};InstallDir]/bin"
+  $ENV{QTDIR}/bin
+)
+
+IF (QT_QMAKE_EXECUTABLE)
+
+  SET(QT4_QMAKE_FOUND FALSE)
+  
+  EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} ARGS "-query QT_VERSION" OUTPUT_VARIABLE QTVERSION)
+
+  # check for qt3 qmake and then try and find qmake4 or qmake-qt4 in the path
+  IF("${QTVERSION}" MATCHES "Unknown")
+    SET(QT_QMAKE_EXECUTABLE NOTFOUND CACHE FILEPATH "" FORCE)
+    FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake4 qmake-qt4 PATHS
+      "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/bin"
+      "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/bin"
+      $ENV{QTDIR}/bin
+      )
+    IF(QT_QMAKE_EXECUTABLE)
+      EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} 
+        ARGS "-query QT_VERSION" OUTPUT_VARIABLE QTVERSION)
+    ENDIF(QT_QMAKE_EXECUTABLE)
+  ENDIF("${QTVERSION}" MATCHES "Unknown")
+
+  # check that we found the Qt4 qmake, Qt3 qmake output won't match here
+  STRING(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" qt_version_tmp "${QTVERSION}")
+  IF (qt_version_tmp)
+
+    # we need at least version 4.0.0
+    IF (NOT QT_MIN_VERSION)
+      SET(QT_MIN_VERSION "4.0.0")
+    ENDIF (NOT QT_MIN_VERSION)
+
+    #now parse the parts of the user given version string into variables
+    STRING(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" req_qt_major_vers "${QT_MIN_VERSION}")
+    IF (NOT req_qt_major_vers)
+      MESSAGE( FATAL_ERROR "Invalid Qt version string given: \"${QT_MIN_VERSION}\", expected e.g. \"4.0.1\"")
+    ENDIF (NOT req_qt_major_vers)
+
+    # now parse the parts of the user given version string into variables
+    STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" req_qt_major_vers "${QT_MIN_VERSION}")
+    STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" req_qt_minor_vers "${QT_MIN_VERSION}")
+    STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" req_qt_patch_vers "${QT_MIN_VERSION}")
+
+    IF (NOT req_qt_major_vers EQUAL 4)
+      MESSAGE( FATAL_ERROR "Invalid Qt version string given: \"${QT_MIN_VERSION}\", major version 4 is required, e.g. \"4.0.1\"")
+    ENDIF (NOT req_qt_major_vers EQUAL 4)
+
+    # and now the version string given by qmake
+    STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" found_qt_major_vers "${QTVERSION}")
+    STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+.*" "\\1" found_qt_minor_vers "${QTVERSION}")
+    STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" found_qt_patch_vers "${QTVERSION}")
+
+    # compute an overall version number which can be compared at once
+    MATH(EXPR req_vers "${req_qt_major_vers}*10000 + ${req_qt_minor_vers}*100 + ${req_qt_patch_vers}")
+    MATH(EXPR found_vers "${found_qt_major_vers}*10000 + ${found_qt_minor_vers}*100 + ${found_qt_patch_vers}")
+
+    IF (found_vers LESS req_vers)
+      SET(QT4_QMAKE_FOUND FALSE)
+      SET(QT4_INSTALLED_VERSION_TOO_OLD TRUE)
+    ELSE (found_vers LESS req_vers)
+      SET(QT4_QMAKE_FOUND TRUE)
+    ENDIF (found_vers LESS req_vers)
+  ENDIF (qt_version_tmp)
+
+ENDIF (QT_QMAKE_EXECUTABLE)
+
+IF (QT4_QMAKE_FOUND)
+
+  if (WIN32)
+    # get qt install dir 
+    get_filename_component(_DIR ${QT_QMAKE_EXECUTABLE} PATH )
+    get_filename_component(QT_INSTALL_DIR ${_DIR} PATH )
+  endif (WIN32)
+
+  # ask qmake for the library dir
+  # Set QT_LIBRARY_DIR
+  IF (NOT QT_LIBRARY_DIR)
+    EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE}
+      ARGS "-query QT_INSTALL_LIBS"
+      OUTPUT_VARIABLE QT_LIBRARY_DIR_TMP )
+    # make sure we have / and not \ as qmake gives on windows
+    FILE(TO_CMAKE_PATH "${QT_LIBRARY_DIR_TMP}" QT_LIBRARY_DIR_TMP)
+    IF(EXISTS "${QT_LIBRARY_DIR_TMP}")
+      SET(QT_LIBRARY_DIR ${QT_LIBRARY_DIR_TMP} CACHE PATH "Qt library dir")
+    ELSE(EXISTS "${QT_LIBRARY_DIR_TMP}")
+      MESSAGE("Warning: QT_QMAKE_EXECUTABLE reported QT_INSTALL_LIBS as ${QT_LIBRARY_DIR_TMP}")
+      MESSAGE("Warning: ${QT_LIBRARY_DIR_TMP} does NOT exist, Qt must NOT be installed correctly.")
+    ENDIF(EXISTS "${QT_LIBRARY_DIR_TMP}")
+  ENDIF(NOT QT_LIBRARY_DIR)
+  
+  IF (APPLE)
+    IF (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework)
+      SET(QT_USE_FRAMEWORKS ON
+        CACHE BOOL "Set to ON if Qt build uses frameworks.")
+    ELSE (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework)
+      SET(QT_USE_FRAMEWORKS OFF
+        CACHE BOOL "Set to ON if Qt build uses frameworks.")
+    ENDIF (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework)
+    
+    MARK_AS_ADVANCED(QT_USE_FRAMEWORKS)
+  ENDIF (APPLE)
+  
+  # ask qmake for the binary dir
+  IF (QT_LIBRARY_DIR AND NOT QT_BINARY_DIR)
+     EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE}
+       ARGS "-query QT_INSTALL_BINS"
+       OUTPUT_VARIABLE qt_bins )
+     # make sure we have / and not \ as qmake gives on windows
+     FILE(TO_CMAKE_PATH "${qt_bins}" qt_bins)
+     SET(QT_BINARY_DIR ${qt_bins} CACHE INTERNAL "")
+  ENDIF (QT_LIBRARY_DIR AND NOT QT_BINARY_DIR)
+
+  # ask qmake for the include dir
+  IF (QT_LIBRARY_DIR AND NOT QT_HEADERS_DIR)
+      EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE}
+        ARGS "-query QT_INSTALL_HEADERS" 
+        OUTPUT_VARIABLE qt_headers ) 
+      # make sure we have / and not \ as qmake gives on windows
+      FILE(TO_CMAKE_PATH "${qt_headers}" qt_headers)
+      SET(QT_HEADERS_DIR ${qt_headers} CACHE INTERNAL "")
+  ENDIF(QT_LIBRARY_DIR AND NOT QT_HEADERS_DIR)
+
+
+  # ask qmake for the documentation directory
+  IF (QT_LIBRARY_DIR AND NOT QT_DOC_DIR)
+    EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE}
+      ARGS "-query QT_INSTALL_DOCS"
+      OUTPUT_VARIABLE qt_doc_dir )
+    # make sure we have / and not \ as qmake gives on windows
+    FILE(TO_CMAKE_PATH "${qt_doc_dir}" qt_doc_dir)
+    SET(QT_DOC_DIR ${qt_doc_dir} CACHE PATH "The location of the Qt docs")
+  ENDIF (QT_LIBRARY_DIR AND NOT QT_DOC_DIR)
+
+  # ask qmake for the mkspecs directory
+  IF (QT_LIBRARY_DIR AND NOT QT_MKSPECS_DIR)
+    EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE}
+      ARGS "-query QMAKE_MKSPECS"
+      OUTPUT_VARIABLE qt_mkspecs_dirs )
+    # do not replace : on windows as it might be a drive letter
+    # and windows should already use ; as a separator
+    IF(UNIX)
+      STRING(REPLACE ":" ";" qt_mkspecs_dirs "${qt_mkspecs_dirs}")
+    ENDIF(UNIX)
+    FIND_PATH(QT_MKSPECS_DIR qconfig.pri PATHS ${qt_mkspecs_dirs}
+      DOC "The location of the Qt mkspecs containing qconfig.pri"
+      NO_DEFAULT_PATH )
+  ENDIF (QT_LIBRARY_DIR AND NOT QT_MKSPECS_DIR)
+
+  # ask qmake for the plugins directory
+  IF (QT_LIBRARY_DIR AND NOT QT_PLUGINS_DIR)
+    EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE}
+      ARGS "-query QT_INSTALL_PLUGINS"
+      OUTPUT_VARIABLE qt_plugins_dir )
+    # make sure we have / and not \ as qmake gives on windows
+    FILE(TO_CMAKE_PATH "${qt_plugins_dir}" qt_plugins_dir)
+    SET(QT_PLUGINS_DIR ${qt_plugins_dir} CACHE PATH "The location of the Qt plugins")
+  ENDIF (QT_LIBRARY_DIR AND NOT QT_PLUGINS_DIR)
+  ########################################
+  #
+  #       Setting the INCLUDE-Variables
+  #
+  ########################################
+
+  FIND_PATH(QT_QTCORE_INCLUDE_DIR QtGlobal
+    ${QT_HEADERS_DIR}/QtCore
+    ${QT_LIBRARY_DIR}/QtCore.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_INCLUDE_DIR by removine "/QtCore" in the string ${QT_QTCORE_INCLUDE_DIR}
+  IF( QT_QTCORE_INCLUDE_DIR AND NOT QT_INCLUDE_DIR)
+    IF (QT_USE_FRAMEWORKS)
+      SET(QT_INCLUDE_DIR ${QT_HEADERS_DIR})
+    ELSE (QT_USE_FRAMEWORKS)
+      STRING( REGEX REPLACE "/QtCore$" "" qt4_include_dir ${QT_QTCORE_INCLUDE_DIR})
+      SET( QT_INCLUDE_DIR ${qt4_include_dir} CACHE PATH "")
+    ENDIF (QT_USE_FRAMEWORKS)
+  ENDIF( QT_QTCORE_INCLUDE_DIR AND NOT QT_INCLUDE_DIR)
+
+  IF( NOT QT_INCLUDE_DIR)
+    IF( NOT Qt4_FIND_QUIETLY AND Qt4_FIND_REQUIRED)
+      MESSAGE( FATAL_ERROR "Could NOT find QtGlobal header")
+    ENDIF( NOT Qt4_FIND_QUIETLY AND Qt4_FIND_REQUIRED)
+  ENDIF( NOT QT_INCLUDE_DIR)
+
+  #############################################
+  #
+  # Find out what window system we're using
+  #
+  #############################################
+  # Save required includes and required_flags variables
+  macro_push_required_vars()
+  # Add QT_INCLUDE_DIR to CMAKE_REQUIRED_INCLUDES
+  SET(CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES};${QT_INCLUDE_DIR}")
+  # On Mac OS X when Qt has framework support, also add the framework path
+  IF( QT_USE_FRAMEWORKS )
+    SET(CMAKE_REQUIRED_FLAGS "-F${QT_LIBRARY_DIR} ")
+  ENDIF( QT_USE_FRAMEWORKS )
+  # Check for Window system symbols (note: only one should end up being set)
+  CHECK_SYMBOL_EXISTS(Q_WS_X11 "QtCore/qglobal.h" Q_WS_X11)
+  CHECK_SYMBOL_EXISTS(Q_WS_WIN "QtCore/qglobal.h" Q_WS_WIN)
+  CHECK_SYMBOL_EXISTS(Q_WS_QWS "QtCore/qglobal.h" Q_WS_QWS)
+  CHECK_SYMBOL_EXISTS(Q_WS_MAC "QtCore/qglobal.h" Q_WS_MAC)
+
+  IF (QT_QTCOPY_REQUIRED)
+     CHECK_SYMBOL_EXISTS(QT_IS_QTCOPY "QtCore/qglobal.h" QT_KDE_QT_COPY)
+     IF (NOT QT_IS_QTCOPY)
+        MESSAGE(FATAL_ERROR "qt-copy is required, but hasn't been found")
+     ENDIF (NOT QT_IS_QTCOPY)
+  ENDIF (QT_QTCOPY_REQUIRED)
+
+  # Restore CMAKE_REQUIRED_INCLUDES+CMAKE_REQUIRED_FLAGS variables
+  macro_pop_required_vars()
+  #
+  #############################################
+
+  IF (QT_USE_FRAMEWORKS)
+    SET(QT_DEFINITIONS ${QT_DEFINITIONS} -F${QT_LIBRARY_DIR} -L${QT_LIBRARY_DIR} )
+  ENDIF (QT_USE_FRAMEWORKS)
+
+  # Set QT_QT3SUPPORT_INCLUDE_DIR
+  FIND_PATH(QT_QT3SUPPORT_INCLUDE_DIR Qt3Support
+    PATHS
+    ${QT_INCLUDE_DIR}/Qt3Support
+    ${QT_LIBRARY_DIR}/Qt3Support.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QT_INCLUDE_DIR
+  FIND_PATH(QT_QT_INCLUDE_DIR qglobal.h
+    PATHS
+    ${QT_INCLUDE_DIR}/Qt
+    ${QT_LIBRARY_DIR}/QtCore.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTGUI_INCLUDE_DIR
+  FIND_PATH(QT_QTGUI_INCLUDE_DIR QtGui
+    PATHS
+    ${QT_INCLUDE_DIR}/QtGui
+    ${QT_LIBRARY_DIR}/QtGui.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTSVG_INCLUDE_DIR
+  FIND_PATH(QT_QTSVG_INCLUDE_DIR QtSvg
+    PATHS
+    ${QT_INCLUDE_DIR}/QtSvg
+    ${QT_LIBRARY_DIR}/QtSvg.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTSCRIPT_INCLUDE_DIR
+  FIND_PATH(QT_QTSCRIPT_INCLUDE_DIR QtScript
+    PATHS
+    ${QT_INCLUDE_DIR}/QtScript
+    ${QT_LIBRARY_DIR}/QtScript.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTTEST_INCLUDE_DIR
+  FIND_PATH(QT_QTTEST_INCLUDE_DIR QtTest
+    PATHS
+    ${QT_INCLUDE_DIR}/QtTest
+    ${QT_LIBRARY_DIR}/QtTest.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTUITOOLS_INCLUDE_DIR
+  FIND_PATH(QT_QTUITOOLS_INCLUDE_DIR QtUiTools
+    PATHS
+    ${QT_INCLUDE_DIR}/QtUiTools
+    ${QT_LIBRARY_DIR}/QtUiTools.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTMOTIF_INCLUDE_DIR
+  IF(Q_WS_X11)
+    FIND_PATH(QT_QTMOTIF_INCLUDE_DIR QtMotif 
+      PATHS 
+      ${QT_INCLUDE_DIR}/QtMotif 
+      NO_DEFAULT_PATH )
+  ENDIF(Q_WS_X11)
+
+  # Set QT_QTNETWORK_INCLUDE_DIR
+  FIND_PATH(QT_QTNETWORK_INCLUDE_DIR QtNetwork
+    PATHS
+    ${QT_INCLUDE_DIR}/QtNetwork
+    ${QT_LIBRARY_DIR}/QtNetwork.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTNSPLUGIN_INCLUDE_DIR
+  FIND_PATH(QT_QTNSPLUGIN_INCLUDE_DIR QtNsPlugin
+    PATHS
+    ${QT_INCLUDE_DIR}/QtNsPlugin
+    ${QT_LIBRARY_DIR}/QtNsPlugin.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTOPENGL_INCLUDE_DIR
+  FIND_PATH(QT_QTOPENGL_INCLUDE_DIR QtOpenGL
+    PATHS
+    ${QT_INCLUDE_DIR}/QtOpenGL
+    ${QT_LIBRARY_DIR}/QtOpenGL.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTSQL_INCLUDE_DIR
+  FIND_PATH(QT_QTSQL_INCLUDE_DIR QtSql
+    PATHS
+    ${QT_INCLUDE_DIR}/QtSql
+    ${QT_LIBRARY_DIR}/QtSql.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTXML_INCLUDE_DIR
+  FIND_PATH(QT_QTXML_INCLUDE_DIR QtXml
+    PATHS
+    ${QT_INCLUDE_DIR}/QtXml
+    ${QT_LIBRARY_DIR}/QtXml.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTASSISTANT_INCLUDE_DIR
+  FIND_PATH(QT_QTASSISTANT_INCLUDE_DIR QtAssistant
+    PATHS
+    ${QT_INCLUDE_DIR}/QtAssistant
+    ${QT_HEADERS_DIR}/QtAssistant
+    ${QT_LIBRARY_DIR}/QtAssistant.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTDESIGNER_INCLUDE_DIR
+  FIND_PATH(QT_QTDESIGNER_INCLUDE_DIR QDesignerComponents
+    PATHS
+    ${QT_INCLUDE_DIR}/QtDesigner
+    ${QT_HEADERS_DIR}/QtDesigner 
+    ${QT_LIBRARY_DIR}/QtDesigner.framework/Headers
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR
+  FIND_PATH(QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR QDesignerComponents
+    PATHS
+    ${QT_INCLUDE_DIR}/QtDesigner
+    ${QT_HEADERS_DIR}/QtDesigner
+    NO_DEFAULT_PATH
+    )
+
+  # Set QT_QTDBUS_INCLUDE_DIR
+  FIND_PATH(QT_QTDBUS_INCLUDE_DIR QtDBus
+    PATHS
+    ${QT_INCLUDE_DIR}/QtDBus
+    ${QT_HEADERS_DIR}/QtDBus
+    ${QT_LIBRARY_DIR}/QtDBus.framework/Headers
+    NO_DEFAULT_PATH
+    )
+  
+  # Set QT_QTASSISTANTCLIENT_INCLUDE_DIR
+  FIND_PATH(QT_QTASSISTANTCLIENT_INCLUDE_DIR QAssistantClient
+    PATHS
+    ${QT_INCLUDE_DIR}/QtAssistant
+    ${QT_HEADERS_DIR}/QtAssistant
+    NO_DEFAULT_PATH
+    )
+  
+  # Set QT_QTHELP_INCLUDE_DIR
+  FIND_PATH(QT_QTHELP_INCLUDE_DIR QtHelp
+    PATHS
+    ${QT_INCLUDE_DIR}/QtHelp
+    ${QT_HEADERS_DIR}/QtHelp
+    NO_DEFAULT_PATH
+    )
+  
+  # Set QT_QTWEBKIT_INCLUDE_DIR
+  FIND_PATH(QT_QTWEBKIT_INCLUDE_DIR QtWebKit
+    PATHS
+    ${QT_INCLUDE_DIR}/QtWebKit
+    ${QT_HEADERS_DIR}/QtWebKit
+    NO_DEFAULT_PATH
+    )
+  
+  # Set QT_QTXMLPATTERNS_INCLUDE_DIR
+  FIND_PATH(QT_QTXMLPATTERNS_INCLUDE_DIR QtXmlPatterns
+    PATHS
+    ${QT_INCLUDE_DIR}/QtXmlPatterns
+    ${QT_HEADERS_DIR}/QtXmlPatterns
+    NO_DEFAULT_PATH
+    )
+  
+  # Set QT_PHONON_INCLUDE_DIR
+  FIND_PATH(QT_PHONON_INCLUDE_DIR phonon
+    PATHS
+    ${QT_INCLUDE_DIR}/phonon
+    NO_DEFAULT_PATH
+    )
+
+  # Make variables changeble to the advanced user
+  MARK_AS_ADVANCED( QT_LIBRARY_DIR QT_INCLUDE_DIR QT_QT_INCLUDE_DIR QT_DOC_DIR QT_MKSPECS_DIR QT_PLUGINS_DIR)
+
+  # Set QT_INCLUDES
+  SET( QT_INCLUDES ${QT_QT_INCLUDE_DIR} ${QT_MKSPECS_DIR}/default ${QT_INCLUDE_DIR} )
+
+  ########################################
+  #
+  #       Setting the LIBRARY-Variables
+  #
+  ########################################
+
+  IF (QT_USE_FRAMEWORKS)
+    # If FIND_LIBRARY found libraries in Apple frameworks, we would NOT have
+    # to jump through these hoops.
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtCore.framework)
+      SET(QT_QTCORE_FOUND TRUE)
+      SET(QT_QTCORE_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtCore" CACHE STRING "The QtCore library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtCore.framework)
+      SET(QT_QTCORE_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtCore.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtGui.framework)
+      SET(QT_QTGUI_FOUND TRUE)
+      SET(QT_QTGUI_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtGui" CACHE STRING "The QtGui library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtGui.framework)
+      SET(QT_QTGUI_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtGui.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/Qt3Support.framework)
+      SET(QT_QT3SUPPORT_FOUND TRUE)
+      SET(QT_QT3SUPPORT_LIBRARY "-F${QT_LIBRARY_DIR} -framework Qt3Support" CACHE STRING "The Qt3Support library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/Qt3Support.framework)
+      SET(QT_QT3SUPPORT_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/Qt3Support.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtNetwork.framework)
+      SET(QT_QTNETWORK_FOUND TRUE)
+      SET(QT_QTNETWORK_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtNetwork" CACHE STRING "The QtNetwork library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtNetwork.framework)
+      SET(QT_QTNETWORK_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtNetwork.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtOpenGL.framework)
+      SET(QT_QTOPENGL_FOUND TRUE)
+      SET(QT_QTOPENGL_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtOpenGL" CACHE STRING "The QtOpenGL library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtOpenGL.framework)
+      SET(QT_QTOPENGL_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtOpenGL.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtSql.framework)
+      SET(QT_QTSQL_FOUND TRUE)
+      SET(QT_QTSQL_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtSql" CACHE STRING "The QtSql library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtSql.framework)
+      SET(QT_QTSQL_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtSql.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtXml.framework)
+      SET(QT_QTXML_FOUND TRUE)
+      SET(QT_QTXML_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtXml" CACHE STRING "The QtXml library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtXml.framework)
+      SET(QT_QTXML_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtXml.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtSvg.framework)
+      SET(QT_QTSVG_FOUND TRUE)
+      SET(QT_QTSVG_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtSvg" CACHE STRING "The QtSvg library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtSvg.framework)
+      SET(QT_QTSVG_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtSvg.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtDBus.framework)
+      SET(QT_QTDBUS_FOUND TRUE)
+      SET(QT_QTDBUS_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtDBus" CACHE STRING "The QtDBus library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtDBus.framework)
+      SET(QT_QTDBUS_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtDBus.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtTest.framework)
+      SET(QT_QTTEST_FOUND TRUE)
+      SET(QT_QTTEST_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtTest" CACHE STRING "The QtTest library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtTest.framework)
+      SET(QT_QTTEST_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtTest.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtAssistantClient.framework)
+      SET(QT_QTASSISTANTCLIENT_FOUND TRUE)
+      SET(QT_QTASSISTANTCLIENT_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtAssistantClient" CACHE STRING "The QtAssistantClient library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtAssistantClient.framework)
+      SET(QT_QTASSISTANTCLIENT_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtAssistantClient.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtWebKit.framework)
+      SET(QT_QTWEBKIT_FOUND TRUE)
+      SET(QT_QTWEBKIT_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtWebKit" CACHE STRING "The QtWebKit library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtWebKit.framework)
+      SET(QT_QTWEBKIT_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtWebKit.framework)
+
+    IF(EXISTS ${QT_LIBRARY_DIR}/QtXmlPatterns.framework)
+      SET(QT_QTXMLPATTERNS_FOUND TRUE)
+      SET(QT_QTXMLPATTERNS_LIBRARY "-F${QT_LIBRARY_DIR} -framework QtXmlPatterns" CACHE STRING "The QtXmlPatterns library.")
+    ELSE(EXISTS ${QT_LIBRARY_DIR}/QtXmlPatterns.framework)
+      SET(QT_QTXMLPATTERNS_FOUND FALSE)
+    ENDIF(EXISTS ${QT_LIBRARY_DIR}/QtXmlPatterns.framework)
+
+
+    # WTF?  why don't we have frameworks?  :P
+    # Set QT_QTUITOOLS_LIBRARY
+    FIND_LIBRARY(QT_QTUITOOLS_LIBRARY NAMES QtUiTools QtUiTools4 PATHS ${QT_LIBRARY_DIR} )
+    # Set QT_QTSCRIPT_LIBRARY
+    FIND_LIBRARY(QT_QTSCRIPT_LIBRARY NAMES QtScript QtScript4    PATHS ${QT_LIBRARY_DIR} )
+
+  ELSE (QT_USE_FRAMEWORKS)
+    
+    # Set QT_QTCORE_LIBRARY by searching for a lib with "QtCore."  as part of the filename
+    FIND_LIBRARY(QT_QTCORE_LIBRARY NAMES QtCore QtCore4 QtCored4 QtCore_debug         PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH )
+
+    # Set QT_QT3SUPPORT_LIBRARY
+    FIND_LIBRARY(QT_QT3SUPPORT_LIBRARY NAMES Qt3Support Qt3Support_debug Qt3Support4 Qt3Supportd4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    # Set QT_QTGUI_LIBRARY
+    FIND_LIBRARY(QT_QTGUI_LIBRARY NAMES QtGui QtGui_debug QtGui_debug QtGui4 QtGuid4            PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    # Set QT_QTMOTIF_LIBRARY
+    IF(Q_WS_X11)
+      FIND_LIBRARY(QT_QTMOTIF_LIBRARY NAMES QtMotif  QtMotif_debug PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+    ENDIF(Q_WS_X11)
+
+    # Set QT_QTNETWORK_LIBRARY
+    FIND_LIBRARY(QT_QTNETWORK_LIBRARY NAMES QtNetwork QtNetwork_debug QtNetwork4 QtNetworkd4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    # Set QT_QTNSPLUGIN_LIBRARY
+    FIND_LIBRARY(QT_QTNSPLUGIN_LIBRARY NAMES QtNsPlugin QtNsPlugin_debug PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    # Set QT_QTOPENGL_LIBRARY
+    FIND_LIBRARY(QT_QTOPENGL_LIBRARY NAMES QtOpenGL QtOpenGL_debug QtOpenGL4 QtOpenGLd4    PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    # Set QT_QTSQL_LIBRARY
+    FIND_LIBRARY(QT_QTSQL_LIBRARY NAMES QtSql QtSql_debug QtSql4 QtSqld4       PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    # Set QT_QTXML_LIBRARY
+    FIND_LIBRARY(QT_QTXML_LIBRARY NAMES QtXml QtXml_debug QtXml4 QtXmld4       PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    # Set QT_QTSVG_LIBRARY
+    FIND_LIBRARY(QT_QTSVG_LIBRARY NAMES QtSvg QtSvg_debug QtSvg4 QtSvgd4       PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    # Set QT_QTSCRIPT_LIBRARY
+    FIND_LIBRARY(QT_QTSCRIPT_LIBRARY NAMES QtScript QtScript_debug QtScript4 QtScriptd4   PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    # Set QT_QTUITOOLS_LIBRARY
+    FIND_LIBRARY(QT_QTUITOOLS_LIBRARY NAMES QtUiTools QtUiTools_debug QtUiTools4 QtUiToolsd4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    # Set QT_QTTEST_LIBRARY
+    FIND_LIBRARY(QT_QTTEST_LIBRARY NAMES QtTest QtTest_debug QtTest4 QtTestd4          PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    FIND_LIBRARY(QT_QTDBUS_LIBRARY NAMES QtDBus QtDBus_debug QtDBus4 QtDBusd4         PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    FIND_LIBRARY(QT_QTASSISTANTCLIENT_LIBRARY NAMES QtAssistantClient QtAssistantClient_debug QtAssistantClient4 QtAssistantClientd4         PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    FIND_LIBRARY(QT_QTHELP_LIBRARY NAMES QtHelp QtHelp_debug QtHelp4 QtHelpd4         PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    FIND_LIBRARY(QT_QTWEBKIT_LIBRARY NAMES QtWebKit QtWebKit_debug QtWebKit4 QtWebKitd4         PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    FIND_LIBRARY(QT_QTXMLPATTERNS_LIBRARY NAMES QtXmlPatterns QtXmlPatterns_debug QtXmlPatterns4 QtXmlPatternsd4         PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+    FIND_LIBRARY(QT_PHONON_LIBRARY NAMES phonon phonon4 phonon_debug phonond4    PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+
+    IF(MSVC)
+      FIND_LIBRARY(QT_QTCORE_LIBRARY_RELEASE    NAMES QtCore4            PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTCORE_LIBRARY_DEBUG      NAMES QtCored4            PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QT3SUPPORT_LIBRARY_RELEASE NAMES Qt3Support4        PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QT3SUPPORT_LIBRARY_DEBUG  NAMES Qt3Supportd4        PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTGUI_LIBRARY_RELEASE     NAMES QtGui4             PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTGUI_LIBRARY_DEBUG       NAMES QtGuid4             PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTNETWORK_LIBRARY_RELEASE NAMES QtNetwork4         PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTNETWORK_LIBRARY_DEBUG   NAMES QtNetworkd4         PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTOPENGL_LIBRARY_RELEASE  NAMES QtOpenGL4          PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTOPENGL_LIBRARY_DEBUG    NAMES QtOpenGLd4          PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTSQL_LIBRARY_RELEASE     NAMES QtSql4             PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTSQL_LIBRARY_DEBUG       NAMES QtSqld4             PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTXML_LIBRARY_RELEASE     NAMES QtXml4             PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTXML_LIBRARY_DEBUG       NAMES QtXmld4             PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTSVG_LIBRARY_RELEASE     NAMES QtSvg4             PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTSVG_LIBRARY_DEBUG       NAMES QtSvgd4             PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTSCRIPT_LIBRARY_RELEASE  NAMES QtScript4          PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTSCRIPT_LIBRARY_DEBUG    NAMES QtScriptd4          PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTUITOOLS_LIBRARY_RELEASE NAMES QtUiTools QtUiTools4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTUITOOLS_LIBRARY_DEBUG   NAMES QtUiToolsd QtUiToolsd4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTTEST_LIBRARY_RELEASE    NAMES QtTest4            PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTTEST_LIBRARY_DEBUG      NAMES QtTestd4            PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTDBUS_LIBRARY_RELEASE    NAMES QtDBus4            PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTDBUS_LIBRARY_DEBUG      NAMES QtDBusd4            PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTASSISTANT_LIBRARY_RELEASE NAMES QtAssistantClient4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTASSISTANT_LIBRARY_DEBUG NAMES QtAssistantClientd4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTDESIGNER_LIBRARY_RELEASE NAMES QtDesigner4            PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTDESIGNER_LIBRARY_DEBUG  NAMES QtDesignerd4            PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTDESIGNERCOMPONENTS_LIBRARY_RELEASE NAMES QtDesignerComponents4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTDESIGNERCOMPONENTS_LIBRARY_DEBUG NAMES QtDesignerComponentsd4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTMAIN_LIBRARY_RELEASE    NAMES qtmain             PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+      FIND_LIBRARY(QT_QTMAIN_LIBRARY_DEBUG      NAMES qtmaind             PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+    ENDIF(MSVC)
+  ENDIF (QT_USE_FRAMEWORKS)
+
+  IF( NOT QT_QTCORE_LIBRARY )
+    IF( NOT Qt4_FIND_QUIETLY AND Qt4_FIND_REQUIRED)
+      MESSAGE( FATAL_ERROR "Could NOT find QtCore. Check ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log for more details.")
+    ENDIF( NOT Qt4_FIND_QUIETLY AND Qt4_FIND_REQUIRED)
+  ENDIF( NOT QT_QTCORE_LIBRARY )
+
+  # Set QT_QTASSISTANT_LIBRARY
+  FIND_LIBRARY(QT_QTASSISTANT_LIBRARY NAMES QtAssistantClient QtAssistantClient4 QtAssistant QtAssistant4 QtAssistantd4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+
+  # Set QT_QTDESIGNER_LIBRARY
+  FIND_LIBRARY(QT_QTDESIGNER_LIBRARY NAMES QtDesigner QtDesigner_debug QtDesigner4 QtDesignerd4 PATHS ${QT_LIBRARY_DIR}        NO_DEFAULT_PATH)
+
+  # Set QT_QTDESIGNERCOMPONENTS_LIBRARY
+  FIND_LIBRARY(QT_QTDESIGNERCOMPONENTS_LIBRARY NAMES QtDesignerComponents QtDesignerComponents_debug QtDesignerComponents4 QtDesignerComponentsd4 PATHS ${QT_LIBRARY_DIR}        NO_DEFAULT_PATH)
+
+  # Set QT_QTMAIN_LIBRARY
+  IF(WIN32)
+    FIND_LIBRARY(QT_QTMAIN_LIBRARY NAMES qtmain qtmaind PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+  ENDIF(WIN32)
+
+  ############################################
+  #
+  # Check the existence of the libraries.
+  #
+  ############################################
+
+  MACRO (_QT4_ADJUST_LIB_VARS basename)
+    IF (QT_${basename}_LIBRARY OR QT_${basename}_LIBRARY_DEBUG)
+
+      IF(MSVC)
+        # Both set
+        IF (QT_${basename}_LIBRARY_RELEASE AND QT_${basename}_LIBRARY_DEBUG)
+          SET(QT_${basename}_LIBRARY optimized ${QT_${basename}_LIBRARY_RELEASE} debug ${QT_${basename}_LIBRARY_DEBUG})
+        ENDIF (QT_${basename}_LIBRARY_RELEASE AND QT_${basename}_LIBRARY_DEBUG)
+
+        # Only debug was found
+        IF (NOT QT_${basename}_LIBRARY_RELEASE AND QT_${basename}_LIBRARY_DEBUG)
+          SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_DEBUG})
+        ENDIF (NOT QT_${basename}_LIBRARY_RELEASE AND QT_${basename}_LIBRARY_DEBUG)
+
+        # Only release was found
+        IF (QT_${basename}_LIBRARY_RELEASE AND NOT QT_${basename}_LIBRARY_DEBUG)
+          SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_RELEASE})
+        ENDIF (QT_${basename}_LIBRARY_RELEASE AND NOT QT_${basename}_LIBRARY_DEBUG)
+
+        # Hmm, is this used anywhere ? Yes, in UseQt4.cmake. We are currently incompatible :-(
+        SET(QT_${basename}_LIBRARIES optimized ${QT_${basename}_LIBRARY} debug ${QT_${basename}_LIBRARY_DEBUG})
+
+      ENDIF(MSVC)
+
+      SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY} CACHE FILEPATH "The Qt ${basename} library")
+
+      IF (QT_${basename}_LIBRARY)
+        SET(QT_${basename}_FOUND 1)
+      ENDIF (QT_${basename}_LIBRARY)
+      
+    ENDIF (QT_${basename}_LIBRARY OR QT_${basename}_LIBRARY_DEBUG)
+    
+    IF (QT_${basename}_INCLUDE_DIR)
+      #add the include directory to QT_INCLUDES
+      SET(QT_INCLUDES "${QT_${basename}_INCLUDE_DIR}" ${QT_INCLUDES})
+    ENDIF (QT_${basename}_INCLUDE_DIR)
+
+    # Make variables changeble to the advanced user
+    MARK_AS_ADVANCED(QT_${basename}_LIBRARY QT_${basename}_INCLUDE_DIR)
+  ENDMACRO (_QT4_ADJUST_LIB_VARS)
+
+
+  # Set QT_xyz_LIBRARY variable and add 
+  # library include path to QT_INCLUDES
+  _QT4_ADJUST_LIB_VARS(QTCORE)
+  _QT4_ADJUST_LIB_VARS(QTGUI)
+  _QT4_ADJUST_LIB_VARS(QT3SUPPORT)
+  _QT4_ADJUST_LIB_VARS(QTASSISTANT)
+  _QT4_ADJUST_LIB_VARS(QTDESIGNER)
+  _QT4_ADJUST_LIB_VARS(QTDESIGNERCOMPONENTS)
+  _QT4_ADJUST_LIB_VARS(QTNETWORK)
+  _QT4_ADJUST_LIB_VARS(QTNSPLUGIN)
+  _QT4_ADJUST_LIB_VARS(QTOPENGL)
+  _QT4_ADJUST_LIB_VARS(QTSQL)
+  _QT4_ADJUST_LIB_VARS(QTXML)
+  _QT4_ADJUST_LIB_VARS(QTSVG)
+  _QT4_ADJUST_LIB_VARS(QTSCRIPT)
+  _QT4_ADJUST_LIB_VARS(QTUITOOLS)
+  _QT4_ADJUST_LIB_VARS(QTTEST)
+  _QT4_ADJUST_LIB_VARS(QTDBUS)
+  _QT4_ADJUST_LIB_VARS(QTASSISTANTCLIENT)
+  _QT4_ADJUST_LIB_VARS(QTHELP)
+  _QT4_ADJUST_LIB_VARS(QTWEBKIT)
+  _QT4_ADJUST_LIB_VARS(QTXMLPATTERNS)
+  _QT4_ADJUST_LIB_VARS(PHONON)
+
+  # platform dependent libraries
+  IF(Q_WS_X11)
+    _QT4_ADJUST_LIB_VARS(QTMOTIF)
+  ENDIF(Q_WS_X11)
+  IF(WIN32)
+    _QT4_ADJUST_LIB_VARS(QTMAIN)
+  ENDIF(WIN32)
+  
+
+  #######################################
+  #
+  #       Check the executables of Qt 
+  #          ( moc, uic, rcc )
+  #
+  #######################################
+
+
+  # find moc and uic using qmake
+  QT_QUERY_QMAKE(QT_MOC_EXECUTABLE_INTERNAL "QMAKE_MOC")
+  QT_QUERY_QMAKE(QT_UIC_EXECUTABLE_INTERNAL "QMAKE_UIC")
+
+  # make sure we have / and not \ as qmake gives on windows
+  FILE(TO_CMAKE_PATH 
+    "${QT_MOC_EXECUTABLE_INTERNAL}" QT_MOC_EXECUTABLE_INTERNAL)
+  # make sure we have / and not \ as qmake gives on windows
+  FILE(TO_CMAKE_PATH 
+    "${QT_UIC_EXECUTABLE_INTERNAL}" QT_UIC_EXECUTABLE_INTERNAL)
+
+  SET(QT_MOC_EXECUTABLE 
+    ${QT_MOC_EXECUTABLE_INTERNAL} CACHE FILEPATH "The moc executable")
+  SET(QT_UIC_EXECUTABLE 
+    ${QT_UIC_EXECUTABLE_INTERNAL} CACHE FILEPATH "The uic executable")
+
+  FIND_PROGRAM(QT_UIC3_EXECUTABLE
+    NAMES uic3
+    PATHS ${QT_BINARY_DIR}
+    NO_DEFAULT_PATH
+    )
+
+  FIND_PROGRAM(QT_RCC_EXECUTABLE 
+    NAMES rcc
+    PATHS ${QT_BINARY_DIR}
+    NO_DEFAULT_PATH
+    )
+
+  FIND_PROGRAM(QT_DBUSCPP2XML_EXECUTABLE 
+    NAMES qdbuscpp2xml
+    PATHS ${QT_BINARY_DIR}
+    NO_DEFAULT_PATH
+    )
+
+  FIND_PROGRAM(QT_DBUSXML2CPP_EXECUTABLE 
+    NAMES qdbusxml2cpp
+    PATHS ${QT_BINARY_DIR}
+    NO_DEFAULT_PATH
+    )
+
+  FIND_PROGRAM(QT_LUPDATE_EXECUTABLE
+    NAMES lupdate
+    PATHS ${QT_BINARY_DIR}
+    NO_DEFAULT_PATH
+    )
+
+  FIND_PROGRAM(QT_LRELEASE_EXECUTABLE
+    NAMES lrelease
+    PATHS ${QT_BINARY_DIR}
+    NO_DEFAULT_PATH
+    )
+
+  IF (QT_MOC_EXECUTABLE)
+     SET(QT_WRAP_CPP "YES")
+  ENDIF (QT_MOC_EXECUTABLE)
+
+  IF (QT_UIC_EXECUTABLE)
+     SET(QT_WRAP_UI "YES")
+  ENDIF (QT_UIC_EXECUTABLE)
+
+
+
+  MARK_AS_ADVANCED( QT_UIC_EXECUTABLE QT_UIC3_EXECUTABLE QT_MOC_EXECUTABLE
+    QT_RCC_EXECUTABLE QT_DBUSXML2CPP_EXECUTABLE QT_DBUSCPP2XML_EXECUTABLE
+    QT_LUPDATE_EXECUTABLE QT_LRELEASE_EXECUTABLE)
+
+  ######################################
+  #
+  #       Macros for building Qt files
+  #
+  ######################################
+
+  MACRO (QT4_EXTRACT_OPTIONS _qt4_files _qt4_options)
+    SET(${_qt4_files})
+    SET(${_qt4_options})
+    SET(_QT4_DOING_OPTIONS FALSE)
+    FOREACH(_currentArg ${ARGN})
+      IF ("${_currentArg}" STREQUAL "OPTIONS")
+        SET(_QT4_DOING_OPTIONS TRUE)
+      ELSE ("${_currentArg}" STREQUAL "OPTIONS")
+        IF(_QT4_DOING_OPTIONS) 
+          LIST(APPEND ${_qt4_options} "${_currentArg}")
+        ELSE(_QT4_DOING_OPTIONS)
+          LIST(APPEND ${_qt4_files} "${_currentArg}")
+        ENDIF(_QT4_DOING_OPTIONS)
+      ENDIF ("${_currentArg}" STREQUAL "OPTIONS")
+    ENDFOREACH(_currentArg) 
+  ENDMACRO (QT4_EXTRACT_OPTIONS)
+
+  MACRO (QT4_GET_MOC_INC_DIRS _moc_INC_DIRS)
+     SET(${_moc_INC_DIRS})
+     GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES)
+
+     FOREACH(_current ${_inc_DIRS})
+        SET(${_moc_INC_DIRS} ${${_moc_INC_DIRS}} "-I" ${_current})
+     ENDFOREACH(_current ${_inc_DIRS})
+
+     # if Qt is installed only as framework, add -F /library/Frameworks to the moc arguments
+     # otherwise moc can't find the headers in the framework include dirs
+     IF(APPLE  AND  "${QT_QTCORE_INCLUDE_DIR}" MATCHES "/Library/Frameworks/")
+        SET(${_moc_INC_DIRS} ${${_moc_INC_DIRS}} "-F/Library/Frameworks")
+     ENDIF(APPLE  AND  "${QT_QTCORE_INCLUDE_DIR}" MATCHES "/Library/Frameworks/")
+
+  ENDMACRO(QT4_GET_MOC_INC_DIRS)
+
+
+  MACRO (QT4_GENERATE_MOC infile outfile )
+  # get include dirs
+     QT4_GET_MOC_INC_DIRS(moc_includes)
+
+     GET_FILENAME_COMPONENT(abs_infile ${infile} ABSOLUTE)
+
+     IF (MSVC_IDE)
+        SET (_moc_parameter_file ${outfile}_parameters)
+        SET (_moc_param "${moc_includes} \n-o${outfile} \n${abs_infile}")
+        STRING(REGEX REPLACE ";-I;" "\\n-I" _moc_param "${_moc_param}")
+        FILE (WRITE ${_moc_parameter_file} "${_moc_param}")
+        ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
+          COMMAND ${QT_MOC_EXECUTABLE}
+          ARGS @"${_moc_parameter_file}"
+          DEPENDS ${abs_infile})
+     ELSE (MSVC_IDE)
+        ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
+           COMMAND ${QT_MOC_EXECUTABLE}
+           ARGS ${moc_includes} -o ${outfile} ${abs_infile}
+           DEPENDS ${abs_infile})
+     ENDIF (MSVC_IDE)
+
+     SET_SOURCE_FILES_PROPERTIES(${outfile} PROPERTIES SKIP_AUTOMOC TRUE)  # dont run automoc on this file
+
+     MACRO_ADD_FILE_DEPENDENCIES(${abs_infile} ${outfile})
+  ENDMACRO (QT4_GENERATE_MOC)
+
+
+  # QT4_WRAP_CPP(outfiles inputfile ... )
+
+  MACRO (QT4_WRAP_CPP outfiles )
+    # get include dirs
+    QT4_GET_MOC_INC_DIRS(moc_includes)
+    QT4_EXTRACT_OPTIONS(moc_files moc_options ${ARGN})
+
+    FOREACH (it ${moc_files})
+      GET_FILENAME_COMPONENT(it ${it} ABSOLUTE)
+      GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
+
+      SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/moc_${outfile}.cxx)
+      ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
+        COMMAND ${QT_MOC_EXECUTABLE}
+        ARGS ${moc_includes} ${moc_options} -o ${outfile} ${it}
+        DEPENDS ${it})
+      SET(${outfiles} ${${outfiles}} ${outfile})
+    ENDFOREACH(it)
+
+  ENDMACRO (QT4_WRAP_CPP)
+
+
+  # QT4_WRAP_UI(outfiles inputfile ... )
+
+  MACRO (QT4_WRAP_UI outfiles )
+    QT4_EXTRACT_OPTIONS(ui_files ui_options ${ARGN})
+
+    FOREACH (it ${ui_files})
+      GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
+      GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
+      SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h)
+      ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
+        COMMAND ${QT_UIC_EXECUTABLE}
+        ARGS ${ui_options} -o ${outfile} ${infile}
+        MAIN_DEPENDENCY ${infile})
+      SET(${outfiles} ${${outfiles}} ${outfile})
+    ENDFOREACH (it)
+
+  ENDMACRO (QT4_WRAP_UI)
+
+
+  # QT4_ADD_RESOURCES(outfiles inputfile ... )
+
+  MACRO (QT4_ADD_RESOURCES outfiles )
+    QT4_EXTRACT_OPTIONS(rcc_files rcc_options ${ARGN})
+
+    FOREACH (it ${rcc_files})
+      GET_FILENAME_COMPONENT(outfilename ${it} NAME_WE)
+      GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
+      GET_FILENAME_COMPONENT(rc_path ${infile} PATH)
+      SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.cxx)
+      #  parse file for dependencies 
+      #  all files are absolute paths or relative to the location of the qrc file
+      FILE(READ "${infile}" _RC_FILE_CONTENTS)
+      STRING(REGEX MATCHALL "]*>" "" _RC_FILE "${_RC_FILE}")
+        STRING(REGEX MATCH "^/|([A-Za-z]:/)" _ABS_PATH_INDICATOR "${_RC_FILE}")
+        IF(NOT _ABS_PATH_INDICATOR)
+          SET(_RC_FILE "${rc_path}/${_RC_FILE}")
+        ENDIF(NOT _ABS_PATH_INDICATOR)
+        SET(_RC_DEPENDS ${_RC_DEPENDS} "${_RC_FILE}")
+      ENDFOREACH(_RC_FILE)
+      ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
+        COMMAND ${QT_RCC_EXECUTABLE}
+        ARGS ${rcc_options} -name ${outfilename} -o ${outfile} ${infile}
+        MAIN_DEPENDENCY ${infile}
+        DEPENDS ${_RC_DEPENDS})
+      SET(${outfiles} ${${outfiles}} ${outfile})
+    ENDFOREACH (it)
+
+  ENDMACRO (QT4_ADD_RESOURCES)
+
+  MACRO(QT4_ADD_DBUS_INTERFACE _sources _interface _basename)
+    GET_FILENAME_COMPONENT(_infile ${_interface} ABSOLUTE)
+    SET(_header ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h)
+    SET(_impl   ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp)
+    SET(_moc    ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc)
+
+    GET_SOURCE_FILE_PROPERTY(_nonamespace ${_interface} NO_NAMESPACE)
+    IF ( _nonamespace )
+        SET(_params -N -m)
+    ELSE ( _nonamespace )
+        SET(_params -m)
+    ENDIF ( _nonamespace )
+
+    GET_SOURCE_FILE_PROPERTY(_include ${_interface} INCLUDE)
+    IF ( _include )
+        SET(_params ${_params} -i ${_include})
+    ENDIF ( _include )
+
+    ADD_CUSTOM_COMMAND(OUTPUT ${_impl} ${_header}
+        COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} ${_params} -p ${_basename} ${_infile}
+        DEPENDS ${_infile})
+  
+    SET_SOURCE_FILES_PROPERTIES(${_impl} PROPERTIES SKIP_AUTOMOC TRUE)
+    
+    QT4_GENERATE_MOC(${_header} ${_moc})
+  
+    SET(${_sources} ${${_sources}} ${_impl} ${_header} ${_moc})
+    MACRO_ADD_FILE_DEPENDENCIES(${_impl} ${_moc})
+  
+  ENDMACRO(QT4_ADD_DBUS_INTERFACE)
+  
+  
+  MACRO(QT4_ADD_DBUS_INTERFACES _sources)
+     FOREACH (_current_FILE ${ARGN})
+        GET_FILENAME_COMPONENT(_infile ${_current_FILE} ABSOLUTE)
+        # get the part before the ".xml" suffix
+        STRING(REGEX REPLACE "(.*[/\\.])?([^\\.]+)\\.xml" "\\2" _basename ${_current_FILE})
+        STRING(TOLOWER ${_basename} _basename)
+        QT4_ADD_DBUS_INTERFACE(${_sources} ${_infile} ${_basename}interface)
+     ENDFOREACH (_current_FILE)
+  ENDMACRO(QT4_ADD_DBUS_INTERFACES)
+  
+  
+  MACRO(QT4_GENERATE_DBUS_INTERFACE _header) # _customName OPTIONS -some -options )
+    QT4_EXTRACT_OPTIONS(_customName _qt4_dbus_options ${ARGN})
+
+    GET_FILENAME_COMPONENT(_in_file ${_header} ABSOLUTE)
+    GET_FILENAME_COMPONENT(_basename ${_header} NAME_WE)
+    
+    IF (_customName)
+      SET(_target ${CMAKE_CURRENT_BINARY_DIR}/${_customName})
+    ELSE (_customName)
+      SET(_target ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.xml)
+    ENDIF (_customName)
+  
+    ADD_CUSTOM_COMMAND(OUTPUT ${_target}
+        COMMAND ${QT_DBUSCPP2XML_EXECUTABLE} ${_qt4_dbus_options} ${_in_file} > ${_target}
+        DEPENDS ${_in_file}
+    )
+  ENDMACRO(QT4_GENERATE_DBUS_INTERFACE)
+  
+  
+  MACRO(QT4_ADD_DBUS_ADAPTOR _sources _xml_file _include _parentClass) # _optionalBasename _optionalClassName)
+    GET_FILENAME_COMPONENT(_infile ${_xml_file} ABSOLUTE)
+    
+    SET(_optionalBasename "${ARGV4}")
+    IF (_optionalBasename)
+       SET(_basename ${_optionalBasename} )
+    ELSE (_optionalBasename)
+       STRING(REGEX REPLACE "(.*[/\\.])?([^\\.]+)\\.xml" "\\2adaptor" _basename ${_infile})
+       STRING(TOLOWER ${_basename} _basename)
+    ENDIF (_optionalBasename)
+
+    SET(_optionalClassName "${ARGV5}")
+    SET(_header ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h)
+    SET(_impl   ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp)
+    SET(_moc    ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc)
+
+    IF(_optionalClassName)
+       ADD_CUSTOM_COMMAND(OUTPUT ${_impl} ${_header}
+          COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -c ${_optionalClassName} -i ${_include} -l ${_parentClass} ${_infile}
+          DEPENDS ${_infile}
+        )
+    ELSE(_optionalClassName)
+       ADD_CUSTOM_COMMAND(OUTPUT ${_impl} ${_header}
+          COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -i ${_include} -l ${_parentClass} ${_infile}
+          DEPENDS ${_infile}
+        )
+    ENDIF(_optionalClassName)
+
+    QT4_GENERATE_MOC(${_header} ${_moc})
+    SET_SOURCE_FILES_PROPERTIES(${_impl} PROPERTIES SKIP_AUTOMOC TRUE)
+    MACRO_ADD_FILE_DEPENDENCIES(${_impl} ${_moc})
+
+    SET(${_sources} ${${_sources}} ${_impl} ${_header} ${_moc})
+  ENDMACRO(QT4_ADD_DBUS_ADAPTOR)
+
+   MACRO(QT4_AUTOMOC)
+      QT4_GET_MOC_INC_DIRS(_moc_INCS)
+
+      SET(_matching_FILES )
+      FOREACH (_current_FILE ${ARGN})
+
+         GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE)
+         # if "SKIP_AUTOMOC" is set to true, we will not handle this file here.
+         # This is required to make uic work correctly:
+         # we need to add generated .cpp files to the sources (to compile them),
+         # but we cannot let automoc handle them, as the .cpp files don't exist yet when
+         # cmake is run for the very first time on them -> however the .cpp files might
+         # exist at a later run. at that time we need to skip them, so that we don't add two
+         # different rules for the same moc file
+         GET_SOURCE_FILE_PROPERTY(_skip ${_abs_FILE} SKIP_AUTOMOC)
+
+         IF ( NOT _skip AND EXISTS ${_abs_FILE} )
+
+            FILE(READ ${_abs_FILE} _contents)
+
+            GET_FILENAME_COMPONENT(_abs_PATH ${_abs_FILE} PATH)
+
+            STRING(REGEX MATCHALL "#include +[^ ]+\\.moc[\">]" _match "${_contents}")
+            IF(_match)
+               FOREACH (_current_MOC_INC ${_match})
+                  STRING(REGEX MATCH "[^ <\"]+\\.moc" _current_MOC "${_current_MOC_INC}")
+
+                  GET_filename_component(_basename ${_current_MOC} NAME_WE)
+   #               SET(_header ${CMAKE_CURRENT_SOURCE_DIR}/${_basename}.h)
+                  SET(_header ${_abs_PATH}/${_basename}.h)
+                  SET(_moc    ${CMAKE_CURRENT_BINARY_DIR}/${_current_MOC})
+                  ADD_CUSTOM_COMMAND(OUTPUT ${_moc}
+                     COMMAND ${QT_MOC_EXECUTABLE}
+                     ARGS ${_moc_INCS} ${_header} -o ${_moc}
+                     DEPENDS ${_header}
+                  )
+
+                  MACRO_ADD_FILE_DEPENDENCIES(${_abs_FILE} ${_moc})
+               ENDFOREACH (_current_MOC_INC)
+            ENDIF(_match)
+         ENDIF ( NOT _skip AND EXISTS ${_abs_FILE} )
+      ENDFOREACH (_current_FILE)
+   ENDMACRO(QT4_AUTOMOC)
+
+
+
+  ######################################
+  #
+  #       decide if Qt got found
+  #
+  ######################################
+
+  # if the includes,libraries,moc,uic and rcc are found then we have it
+  IF( QT_LIBRARY_DIR AND QT_INCLUDE_DIR AND QT_MOC_EXECUTABLE AND QT_UIC_EXECUTABLE AND QT_RCC_EXECUTABLE)
+    SET( QT4_FOUND "YES" )
+    IF( NOT Qt4_FIND_QUIETLY)
+      MESSAGE(STATUS "Found Qt-Version ${QTVERSION} (using ${QT_QMAKE_EXECUTABLE})")
+    ENDIF( NOT Qt4_FIND_QUIETLY)
+  ELSE( QT_LIBRARY_DIR AND QT_INCLUDE_DIR AND QT_MOC_EXECUTABLE AND QT_UIC_EXECUTABLE AND QT_RCC_EXECUTABLE)
+    SET( QT4_FOUND "NO")
+    SET(QT_QMAKE_EXECUTABLE "${QT_QMAKE_EXECUTABLE}-NOTFOUND" CACHE FILEPATH "Invalid qmake found" FORCE)
+    IF( Qt4_FIND_REQUIRED)
+      IF ( NOT QT_LIBRARY_DIR )
+        MESSAGE(STATUS "Qt libraries NOT found!")
+      ENDIF(NOT QT_LIBRARY_DIR )
+      IF ( NOT QT_INCLUDE_DIR )
+        MESSAGE(STATUS "Qt includes NOT found!")
+      ENDIF( NOT QT_INCLUDE_DIR )
+      IF ( NOT QT_MOC_EXECUTABLE )
+        MESSAGE(STATUS "Qt's moc NOT found!")
+      ENDIF( NOT QT_MOC_EXECUTABLE )
+      IF ( NOT QT_UIC_EXECUTABLE )
+        MESSAGE(STATUS "Qt's uic NOT found!")
+      ENDIF( NOT QT_UIC_EXECUTABLE )
+      IF ( NOT QT_RCC_EXECUTABLE )
+        MESSAGE(STATUS "Qt's rcc NOT found!")
+      ENDIF( NOT QT_RCC_EXECUTABLE )
+      MESSAGE( FATAL_ERROR "Qt libraries, includes, moc, uic or/and rcc NOT found!")
+    ENDIF( Qt4_FIND_REQUIRED)
+  ENDIF( QT_LIBRARY_DIR AND QT_INCLUDE_DIR AND QT_MOC_EXECUTABLE AND QT_UIC_EXECUTABLE AND  QT_RCC_EXECUTABLE)
+  SET(QT_FOUND ${QT4_FOUND})
+
+
+  #######################################
+  #
+  #       System dependent settings  
+  #
+  #######################################
+  # for unix add X11 stuff
+  IF(UNIX)
+    # on OS X X11 may not be required
+    IF (Q_WS_X11)
+      FIND_PACKAGE(X11 REQUIRED)
+    ENDIF (Q_WS_X11)
+    FIND_PACKAGE(Threads)
+    SET(QT_QTCORE_LIBRARY ${QT_QTCORE_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
+  ENDIF(UNIX)
+
+
+  #######################################
+  #
+  #       compatibility settings 
+  #
+  #######################################
+  # Backwards compatibility for CMake1.4 and 1.2
+  SET (QT_MOC_EXE ${QT_MOC_EXECUTABLE} )
+  SET (QT_UIC_EXE ${QT_UIC_EXECUTABLE} )
+
+  SET( QT_QT_LIBRARY "")
+
+ELSE(QT4_QMAKE_FOUND)
+   
+   SET(QT_QMAKE_EXECUTABLE "${QT_QMAKE_EXECUTABLE}-NOTFOUND" CACHE FILEPATH "Invalid qmake found" FORCE)
+   IF(Qt4_FIND_REQUIRED)
+      IF(QT4_INSTALLED_VERSION_TOO_OLD)
+         MESSAGE(FATAL_ERROR "The installed Qt version ${QTVERSION} is too old, at least version ${QT_MIN_VERSION} is required")
+      ELSE(QT4_INSTALLED_VERSION_TOO_OLD)
+         MESSAGE( FATAL_ERROR "Qt qmake not found!")
+      ENDIF(QT4_INSTALLED_VERSION_TOO_OLD)
+   ELSE(Qt4_FIND_REQUIRED)
+      IF(QT4_INSTALLED_VERSION_TOO_OLD AND NOT Qt4_FIND_QUIETLY)
+         MESSAGE(STATUS "The installed Qt version ${QTVERSION} is too old, at least version ${QT_MIN_VERSION} is required")
+      ENDIF(QT4_INSTALLED_VERSION_TOO_OLD AND NOT Qt4_FIND_QUIETLY)
+   ENDIF(Qt4_FIND_REQUIRED)
+ 
+ENDIF (QT4_QMAKE_FOUND)
+ENDIF (QT4_QMAKE_FOUND)
+
diff --git a/cmake/modules/FindSWIG.cmake b/cmake/modules/FindSWIG.cmake
new file mode 100644
index 0000000..9c18544
--- /dev/null
+++ b/cmake/modules/FindSWIG.cmake
@@ -0,0 +1,60 @@
+# - Find SWIG
+# This module finds an installed SWIG.  It sets the following variables:
+#  SWIG_FOUND - set to true if SWIG is found
+#  SWIG_DIR - the directory where swig is installed
+#  SWIG_EXECUTABLE - the path to the swig executable
+
+SET(SWIG_FOUND FOOBAR)
+
+
+FILE(GLOB_RECURSE SWIGSWG /usr/share/swig/swig.swg)
+FILE(GLOB_RECURSE SWIGCONFIG /usr/share/swig/SWIGConfig.cmake)
+
+FOREACH(_file ${SWIGCONFIG} ${SWIGSWG} )
+	GET_FILENAME_COMPONENT(SWIG_DIR ${_file} PATH)
+ENDFOREACH(_file)
+
+FIND_PATH(SWIG_DIR
+  SWIGConfig.cmake
+  /usr/share/swig1.3
+  /usr/lib/swig1.3
+  /usr/local/share/swig1.3)
+
+FIND_PATH(SWIG_DIR
+  swig.swg
+  /usr/share/swig1.3
+  /usr/lib/swig1.3
+  /usr/local/share/swig1.3)
+
+IF(EXISTS ${SWIG_DIR})
+  IF("x${SWIG_DIR}x" STREQUAL "x${CMAKE_ROOT}/Modulesx")
+    MESSAGE("SWIG_DIR should not be modules subdirectory of CMake")
+  ENDIF("x${SWIG_DIR}x" STREQUAL "x${CMAKE_ROOT}/Modulesx")
+
+  IF(EXISTS ${SWIG_DIR}/SWIGConfig.cmake)
+    INCLUDE(${SWIG_DIR}/SWIGConfig.cmake)
+    SET(SWIG_FOUND 1)
+  ELSE(EXISTS ${SWIG_DIR}/SWIGConfig.cmake)
+    FIND_PROGRAM(SWIG_EXECUTABLE
+      NAMES swig-1.3 swig
+      PATHS ${SWIG_DIR} ${SWIG_DIR}/.. ${SWIG_DIR}/../../bin /usr/bin /usr/local/bin )
+    SET(SWIG_USE_FILE ${CMAKE_ROOT}/Modules/UseSWIG.cmake)
+  ENDIF(EXISTS ${SWIG_DIR}/SWIGConfig.cmake)
+ENDIF(EXISTS ${SWIG_DIR})
+
+IF("x${SWIG_FOUND}x" STREQUAL "xFOOBARx")
+  SET(SWIG_FOUND 0)
+  IF(EXISTS ${SWIG_DIR})
+    IF(EXISTS ${SWIG_USE_FILE})
+      IF(EXISTS ${SWIG_EXECUTABLE})
+        SET(SWIG_FOUND 1)
+	MESSAGE(STATUS "Found SWIG: ${SWIG_EXECUTABLE}" )
+      ENDIF(EXISTS ${SWIG_EXECUTABLE})
+    ENDIF(EXISTS ${SWIG_USE_FILE})
+  ENDIF(EXISTS ${SWIG_DIR})
+  IF(NOT ${SWIG_FOUND})
+    IF(${SWIG_FIND_REQUIRED})
+      MESSAGE(FATAL_ERROR "SWIG was not found on the system. Please specify the location of SWIG.")
+    ENDIF(${SWIG_FIND_REQUIRED})
+  ENDIF(NOT ${SWIG_FOUND})
+ENDIF("x${SWIG_FOUND}x" STREQUAL "xFOOBARx")
diff --git a/cmake/modules/FindSqlite.cmake b/cmake/modules/FindSqlite.cmake
new file mode 100644
index 0000000..fe5ae26
--- /dev/null
+++ b/cmake/modules/FindSqlite.cmake
@@ -0,0 +1,53 @@
+# - Try to find the sqlite library
+# Once done this will define
+#
+#  SQLITE_FOUND - system has sqlite
+#  SQLITE_INCLUDE_DIRS - the sqlite include directory
+#  SQLITE_LIBRARIES - Link these to use sqlite
+#
+#  Copyright (c) 2008 Bjoern Ricks 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#	
+
+INCLUDE( FindPkgConfig )
+
+IF ( Sqlite_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( Sqlite_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( Sqlite_FIND_REQUIRED )
+
+IF ( SQLITE_MIN_VERSION )
+	PKG_SEARCH_MODULE( SQLITE ${_pkgconfig_REQUIRED} sqlite>=${SQLITE_MIN_VERSION} )
+ELSE ( SQLITE_MIN_VERSION )
+	PKG_SEARCH_MODULE( SQLITE ${_pkgconfig_REQUIRED} sqlite )
+ENDIF ( SQLITE_MIN_VERSION )
+
+
+IF( NOT SQLITE_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( SQLITE_INCLUDE_DIRS sqlite.h )
+	FIND_LIBRARY( SQLITE_LIBRARIES sqlite )
+
+	# Report results
+	IF ( SQLITE_LIBRARIES AND SQLITE_INCLUDE_DIRS )	
+		SET( SQLITE_FOUND 1 )
+		IF ( NOT Sqlite_FIND_QUIETLY )
+			MESSAGE( STATUS "Found Sqlite: ${SQLITE_LIBRARIES}" )
+		ENDIF ( NOT Sqlite_FIND_QUIETLY )
+	ELSE ( SQLITE_LIBRARIES AND SQLITE_INCLUDE_DIRS )	
+		IF ( Sqlite_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find Sqlite" )
+		ELSE ( Sqlite_FIND_REQUIRED )
+			IF ( NOT Sqlite_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find Sqlite" )	
+			ENDIF ( NOT Sqlite_FIND_QUIETLY )
+		ENDIF ( Sqlite_FIND_REQUIRED )
+	ENDIF ( SQLITE_LIBRARIES AND SQLITE_INCLUDE_DIRS )	
+ENDIF( NOT SQLITE_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( SQLITE_LIBRARIES SQLITE_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindSqlite3.cmake b/cmake/modules/FindSqlite3.cmake
new file mode 100644
index 0000000..9ff5cc2
--- /dev/null
+++ b/cmake/modules/FindSqlite3.cmake
@@ -0,0 +1,82 @@
+# - Try to find sqlite3 
+# Find sqlite3 headers, libraries and the answer to all questions.
+#
+#  SQLITE3_FOUND               True if sqlite3 got found
+#  SQLITE3_INCLUDEDIR          Location of sqlite3 headers 
+#  SQLITE3_LIBRARIES           List of libaries to use sqlite3
+#  SQLITE3_DEFINITIONS         Definitions to compile sqlite3 
+#
+# Copyright (c) 2007 Juha Tuomala 
+# Copyright (c) 2007 Daniel Gollub 
+# Copyright (c) 2007 Alban Browaeys 
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+# Take care about sqlite3.pc settings
+IF ( Sqlite3_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE ( Sqlite3_FIND_REQUIRED )
+  SET( _pkgconfig_REQUIRED "" )
+ENDIF ( Sqlite3_FIND_REQUIRED )
+
+IF ( SQLITE3_MIN_VERSION )
+	PKG_SEARCH_MODULE( SQLITE3 ${_pkgconfig_REQUIRED} sqlite3>=${SQLITE3_MIN_VERSION} )
+ELSE ( SQLITE3_MIN_VERSION )
+	pkg_search_module( SQLITE3 ${_pkgconfig_REQUIRED} sqlite3 )
+ENDIF ( SQLITE3_MIN_VERSION )
+
+
+# Look for sqlite3 include dir and libraries w/o pkgconfig
+IF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND )
+	FIND_PATH( _sqlite3_include_DIR sqlite3.h 
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+	)
+	FIND_LIBRARY( _sqlite3_link_DIR sqlite3 
+		PATHS
+		/opt/local/lib
+		/sw/lib
+		/usr/lib
+		/usr/local/lib
+		/usr/lib64
+		/usr/local/lib64
+		/opt/lib64
+	)
+	IF ( _sqlite3_include_DIR AND _sqlite3_link_DIR )
+		SET ( _sqlite3_FOUND TRUE )
+	ENDIF ( _sqlite3_include_DIR AND _sqlite3_link_DIR )
+
+
+	IF ( _sqlite3_FOUND )
+		SET ( SQLITE3_INCLUDE_DIRS ${_sqlite3_include_DIR} )
+		SET ( SQLITE3_LIBRARIES ${_sqlite3_link_DIR} )
+	ENDIF ( _sqlite3_FOUND )
+
+	# Report results
+	IF ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )	
+		SET( SQLITE3_FOUND 1 )
+		IF ( NOT Sqlite3_FIND_QUIETLY )
+			MESSAGE( STATUS "Found sqlite3: ${SQLITE3_LIBRARIES} ${SQLITE3_INCLUDE_DIRS}" )
+		ENDIF ( NOT Sqlite3_FIND_QUIETLY )
+	ELSE ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )	
+		IF ( Sqlite3_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find sqlite3" )
+		ELSE ( Sqlite3_FIND_REQUIRED )
+			IF ( NOT Sqlite3_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find sqlite3" )	
+			ENDIF ( NOT Sqlite3_FIND_QUIETLY )
+		ENDIF ( Sqlite3_FIND_REQUIRED )
+	ENDIF ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )	
+
+ENDIF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND )
+
+# Hide advanced variables from CMake GUIs
+MARK_AS_ADVANCED( SQLITE3_LIBRARIES SQLITE3_INCLUDE_DIRS )
+
diff --git a/cmake/modules/FindThunderbirdXpcom.cmake b/cmake/modules/FindThunderbirdXpcom.cmake
new file mode 100644
index 0000000..c8baabc
--- /dev/null
+++ b/cmake/modules/FindThunderbirdXpcom.cmake
@@ -0,0 +1,249 @@
+# ======================================================
+# This file is part of the mozilla-sync plugin for OpenSync
+# See http://www.KaarPoSoft.dk/bluezync
+# $Id: FindThunderbirdXpcom.cmake 5886 2009-10-22 15:20:12Z henrik $
+# ======================================================
+
+# The purpose of this CMake file is to find Thunderbird and Sunbird files and versions.
+# It should work with Icedove and Iceowl as well
+
+# First we look for a Thunderbird package
+PKG_SEARCH_MODULE ( THUNDERBIRD_XPCOM thunderbird-xpcom icedove-xpcom )
+
+IF ( THUNDERBIRD_XPCOM_FOUND )
+
+	# If we found the Thunderbird package, look for one of the includes, just to be sure
+	FIND_PATH ( THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR mozilla-config.h
+		PATHS ${THUNDERBIRD_XPCOM_INCLUDE_DIRS} )
+	IF( NOT THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR )
+		MESSAGE ( FATAL_ERROR "*** *** Found Thunderbird package, but not mozilla-config.h" )
+	ENDIF ( NOT THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR )
+	# We also need NSPR, so let's make sure it is there
+	FIND_PATH ( NSPR_MAIN_INCLUDE_DIR nspr.h
+		PATHS ${THUNDERBIRD_XPCOM_INCLUDE_DIRS} )
+	IF( NOT NSPR_MAIN_INCLUDE_DIR )
+		MESSAGE ( FATAL_ERROR "*** *** Found Thunderbird package, but not nspr.h" )
+	ENDIF ( NOT NSPR_MAIN_INCLUDE_DIR )
+
+ELSE( THUNDERBIRD_XPCOM_FOUND )
+
+	# We did not find a Thunderbird package, so let us look for the files manually 
+	MESSAGE ( STATUS "  did not find thunderbird package; now looking for thunderbird files" )
+	FIND_PATH (THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR mozilla-config.h
+		PATH_SUFFIXES thunderbird icedove
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+		/usr/lib64/mozilla-thunderbird/include/
+	)
+	IF ( NOT THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR )
+		MESSAGE ( FATAL_ERROR "*** *** Did not find Thunderbird include directory with mozilla-config.h" )
+	ENDIF ( NOT THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR )
+	FIND_PATH ( NSPR_MAIN_INCLUDE_DIR nspr.h
+		PATH_SUFFIXES nspr nspr4 thunderbird/nspr
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+	)
+	IF( NOT NSPR_MAIN_INCLUDE_DIR )
+		MESSAGE ( FATAL_ERROR "*** *** Found Thunderbird include directory, but not nspr.h" )
+	ENDIF ( NOT NSPR_MAIN_INCLUDE_DIR )
+	# Usually all the libraries are in one directory, so let us try to find it
+	FIND_LIBRARY ( _xpcom_lib NAMES xpcom libxpcom
+		PATH_SUFFIXES thunderbird icedove
+		PATHS
+		/opt/local/lib
+		/sw/lib
+		/usr/lib
+		/usr/local/lib
+		/usr/lib64
+		/usr/local/lib64
+		/opt/lib64
+	)
+
+	IF ( WIN32 AND NOT _xpcom_lib )
+		GET_FILENAME_COMPONENT ( _tbdir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\thunderbird.exe]" PATH CACHE)
+	FIND_LIBRARY ( _xpcom_lib NAMES xpcom libxpcom
+		PATHS "${_tbdir}"
+	)
+	ENDIF ( WIN32 AND NOT _xpcom_lib )
+
+	IF ( NOT _xpcom_lib )
+		MESSAGE ( FATAL_ERROR "*** *** Found Thunderbird, but not the xpcom library" )
+	ENDIF ( NOT _xpcom_lib )
+	# We got the actual library, but we need the directory
+	GET_FILENAME_COMPONENT ( THUNDERBIRD_XPCOM_LIBRARY_DIRS "${_xpcom_lib}" PATH )
+	# Usually the only library we need is the xpcom
+	SET ( THUNDERBIRD_XPCOM_LIBRARIES "xpcom" )
+
+	IF ( WIN32 )
+		SET ( THUNDERBIRD_XPCOM_LIBRARIES "xpcom;xpcom_compat;xpcom_core;xpistub" )
+	ENDIF ( WIN32 )
+
+	# For Thunderbird 3.0 we need to link the glue library
+	EXEC_PROGRAM ( thunderbird ARGS "--version"
+		OUTPUT_VARIABLE THUNDERBIRD_XPCOM_VERSION
+		RETURN_VALUE _THUNDERBIRD_XPCOM_VERSION_RET )
+
+	IF ( _THUNDERBIRD_XPCOM_VERSION_RET )
+		EXEC_PROGRAM ( icedove ARGS "--version"
+			OUTPUT_VARIABLE THUNDERBIRD_XPCOM_VERSION
+			RETURN_VALUE _THUNDERBIRD_XPCOM_VERSION_RET )
+	ENDIF ( _THUNDERBIRD_XPCOM_VERSION_RET )
+
+	IF ( WIN32 AND _THUNDERBIRD_XPCOM_VERSION_RET )
+		GET_FILENAME_COMPONENT ( _tb_exe "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\thunderbird.exe]" ABSOLUTE CACHE)
+		EXEC_PROGRAM ( "${_tb_exe}" ARGS "--version"
+			OUTPUT_VARIABLE THUNDERBIRD_XPCOM_VERSION
+			RETURN_VALUE _THUNDERBIRD_XPCOM_VERSION_RET )
+	ENDIF ( WIN32 AND  _THUNDERBIRD_XPCOM_VERSION_RET )
+
+	IF (_THUNDERBIRD_XPCOM_VERSION_RET )
+			MESSAGE ( FATAL_ERROR "*** *** Unable execute Thunderbird/Icedove to get its version" )
+	ENDIF ( _THUNDERBIRD_XPCOM_VERSION_RET )
+
+	STRING ( REGEX MATCH ".* ([0-9]\\.[0-9]).*" _THUNDERBIRD_XPCOM_VERSION_OK "${THUNDERBIRD_XPCOM_VERSION}" )
+	IF ( _THUNDERBIRD_XPCOM_VERSION_OK )
+		STRING (REGEX REPLACE ".* ([0-9]\\.[0-9]).*" "\\1" THUNDERBIRD_XPCOM_VERSION "${THUNDERBIRD_XPCOM_VERSION}" )
+	ENDIF ( _THUNDERBIRD_XPCOM_VERSION_OK )
+
+ENDIF( THUNDERBIRD_XPCOM_FOUND )
+
+STRING ( REGEX MATCH ".*([0-9]\\.[0-9]).*" _THUNDERBIRD_XPCOM_VERSION_OK "${THUNDERBIRD_XPCOM_VERSION}" )
+IF ( _THUNDERBIRD_XPCOM_VERSION_OK )
+	# Thunderbird main version
+	STRING (REGEX REPLACE "^([0-9]+)\\..*$" "\\1" THUNDERBIRD_VERSION_MAIN "${THUNDERBIRD_XPCOM_VERSION}" )
+ELSE ( _THUNDERBIRD_XPCOM_VERSION_OK )
+	MESSAGE ( STATUS "Unable to interpret Thunderbird version [${THUNDERBIRD_XPCOM_VERSION}]; continuing anyway" )
+ENDIF ( _THUNDERBIRD_XPCOM_VERSION_OK )
+
+# Thunderbird 3
+IF ( THUNDERBIRD_VERSION_MAIN STREQUAL "3" )
+	SET ( THUNDERBIRD_XPCOM_LIBRARIES "xpcomglue_s;xpcom" )
+	IF ( WIN32 )
+		SET ( THUNDERBIRD_XPCOM_LIBRARIES "xpcomglue_s;xpcom;nspr4" )
+	ENDIF ( WIN32 )
+ENDIF ( THUNDERBIRD_VERSION_MAIN STREQUAL "3" )
+
+# So, by now we should have the following variables set:
+MESSAGE ( STATUS "    THUNDERBIRD_XPCOM_VERSION ${THUNDERBIRD_XPCOM_VERSION}" )
+MESSAGE ( STATUS "    THUNDERBIRD_VERSION_MAIN ${THUNDERBIRD_VERSION_MAIN}" )
+MESSAGE ( STATUS "    THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR ${THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR}" )
+MESSAGE ( STATUS "    NSPR_MAIN_INCLUDE_DIR ${NSPR_MAIN_INCLUDE_DIR}" )
+MESSAGE ( STATUS "    THUNDERBIRD_XPCOM_LIBRARY_DIRS ${THUNDERBIRD_XPCOM_LIBRARY_DIRS}" )
+MESSAGE ( STATUS "    THUNDERBIRD_XPCOM_LIBRARIES ${THUNDERBIRD_XPCOM_LIBRARIES}" )
+
+# Those are the include directories we actually need
+SET ( XPCOM_INCLUDE_DIRS 
+	${NSPR_MAIN_INCLUDE_DIR}
+	${THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR}
+	${THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR}/addrbook
+	${THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR}/extensions
+	${THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR}/rdf
+	${THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR}/string
+	${THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR}/xpcom_obsolete
+	${THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR}/xpcom
+	${THUNDERBIRD_XPCOM_MAIN_INCLUDE_DIR}/xulapp
+)
+
+
+# ----------------------------------------
+
+# Now look for a Subird package
+PKG_SEARCH_MODULE ( SUNBIRD sunbird-xpcom iceowl-xpcom  )
+
+IF ( SUNBIRD_FOUND )
+
+	# If we found the Thunderbird package, let us try to find the main include dir
+	MESSAGE ( "  SUNBIRD_INCLUDE_DIRS ${SUNBIRD_INCLUDE_DIRS}" )
+	# ---------- We just need the first directory, which should be the main directory
+	# The rest will point to xpcom and friends; and we do not want that.
+	# But, let's also handle the special case of only one direcory reported, just in case
+	STRING ( REGEX MATCH ";" _SEVERAL_INCLUDE_DIRS "${SUNBIRD_INCLUDE_DIRS}" )
+	IF ( _SEVERAL_INCLUDE_DIRS )
+		MESSAGE ( "SEVERAL")
+		STRING ( REGEX REPLACE "([^;]*);.*" "\\1" SUNBIRD_MAIN_INCLUDE_DIR "${SUNBIRD_INCLUDE_DIRS}" )
+	ELSE ( _SEVERAL_INCLUDE_DIRS )
+		SET ( SUNBIRD_MAIN_INCLUDE_DIR "${SUNBIRD_INCLUDE_DIRS}" )
+	ENDIF ( _SEVERAL_INCLUDE_DIRS )
+
+ELSE( SUNBIRD_FOUND )
+
+	# We did not find a Sunbird package, so let us look for the files manually 
+	MESSAGE ( STATUS "  did not find sunbird package; now looking for sunbird files" )
+	FIND_PATH ( SUNBIRD_MAIN_INCLUDE_DIR calbase/calIICSService.h
+		PATH_SUFFIXES sunbird iceowl
+		PATHS
+		/opt/local/include/
+		/sw/include/
+		/usr/local/include/
+		/usr/include/
+	)
+	IF ( NOT SUNBIRD_MAIN_INCLUDE_DIR )
+		MESSAGE ( FATAL_ERROR "*** *** Did not find Sunbird include directory with mozilla-config.h" )
+	ENDIF ( NOT SUNBIRD_MAIN_INCLUDE_DIR )
+
+	# We need the Sunbird version number
+	EXEC_PROGRAM ( sunbird ARGS "--version"
+		OUTPUT_VARIABLE SUNBIRD_VERSION
+		RETURN_VALUE _SUNBIRD_VERSION_RET )
+	IF ( _SUNBIRD_VERSION_RET )
+
+	EXEC_PROGRAM ( iceowl ARGS "--version"
+		OUTPUT_VARIABLE SUNBIRD_VERSION
+		RETURN_VALUE _SUNBIRD_VERSION_RET )
+	ENDIF ( _SUNBIRD_VERSION_RET )
+
+	IF ( WIN32 AND _SUNBIRD_VERSION_RET )
+		GET_FILENAME_COMPONENT ( _sb_exe "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\sunbird.exe]" ABSOLUTE CACHE)
+		EXEC_PROGRAM ( "${_sb_exe}" ARGS "--version"
+			OUTPUT_VARIABLE SUNBIRD_VERSION
+			RETURN_VALUE _SUNBIRD_VERSION_RET )
+	ENDIF ( WIN32 AND _SUNBIRD_VERSION_RET )
+
+	IF ( _SUNBIRD_VERSION_RET )
+		MESSAGE ( FATAL_ERROR "*** *** Unable execute sunbird/iceowl to get its version" )
+	ENDIF ( _SUNBIRD_VERSION_RET )
+
+	STRING ( REGEX MATCH ".* ([0-9]\\.[0-9]).*" _SUNBIRD_VERSION_OK "${SUNBIRD_VERSION}" )
+	IF ( _SUNBIRD_VERSION_OK )
+		STRING (REGEX REPLACE ".* ([0-9]\\.[0-9]).*" "\\1" SUNBIRD_VERSION "${SUNBIRD_VERSION}" )
+	ENDIF ( _SUNBIRD_VERSION_OK )
+
+ENDIF ( SUNBIRD_FOUND )
+
+STRING ( REGEX MATCH ".*([0-9]\\.[0-9]).*" _SUNBIRD_VERSION_OK "${SUNBIRD_VERSION}" )
+IF ( _SUNBIRD_VERSION_OK )
+	# Sunbird main version
+	STRING (REGEX REPLACE "^([0-9]+)\\..*$" "\\1" SUNBIRD_VERSION_MAIN "${SUNBIRD_VERSION}" )
+ELSE ( _SUNBIRD_VERSION_OK )
+	MESSAGE ( FATAL_ERROR "*** ***Unable to interpret Sunbird version [${_SUNBIRD_VERSION}]" )
+ENDIF ( _SUNBIRD_VERSION_OK )
+
+
+
+# ----------------------------------------
+
+# So, by now we should have the following variables set:
+MESSAGE ( STATUS "     SUNBIRD_MAIN_INCLUDE_DIR ${SUNBIRD_MAIN_INCLUDE_DIR}" )
+MESSAGE ( STATUS "     SUNBIRD_VERSION ${SUNBIRD_VERSION}" )
+
+# Set the final output variables
+SET ( XPCOM_INCLUDE_DIRS "${XPCOM_INCLUDE_DIRS};${SUNBIRD_MAIN_INCLUDE_DIR}" )
+SET ( XPCOM_LIBRARY_DIRS "${THUNDERBIRD_XPCOM_LIBRARY_DIRS}" )
+SET ( XPCOM_LIBRARIES "${THUNDERBIRD_XPCOM_LIBRARIES}" )
+
+# And here is what we found out:
+MESSAGE ( STATUS "Found xpcom (thunderbird and sunbird):" )
+MESSAGE ( STATUS "  THUNDERBIRD_XPCOM_VERSION=[${THUNDERBIRD_XPCOM_VERSION}]" )
+MESSAGE ( STATUS "  SUNBIRD_VERSION=[${SUNBIRD_VERSION}]" )
+MESSAGE ( STATUS "  THUNDERBIRD_VERSION_MAIN=[${THUNDERBIRD_VERSION_MAIN}]" )
+MESSAGE ( STATUS "  SUNBIRD_VERSION_MAIN=[${SUNBIRD_VERSION_MAIN}]" )
+MESSAGE ( STATUS "  XPCOM_INCLUDE_DIRS ${XPCOM_INCLUDE_DIRS}" )
+MESSAGE ( STATUS "  XPCOM_LIBRARY_DIRS ${XPCOM_LIBRARY_DIRS}" )
+MESSAGE ( STATUS "  XPCOM_LIBRARIES ${XPCOM_LIBRARIES}" )
+MESSAGE ( STATUS "  SUNBIRD_VERSION ${SUNBIRD_VERSION}" )
diff --git a/cmake/modules/MacroEnsureOutOfSourceBuild.cmake b/cmake/modules/MacroEnsureOutOfSourceBuild.cmake
new file mode 100644
index 0000000..094f2df
--- /dev/null
+++ b/cmake/modules/MacroEnsureOutOfSourceBuild.cmake
@@ -0,0 +1,17 @@
+# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD()
+# MACRO_ENSURE_OUT_OF_SOURCE_BUILD()
+
+# Copyright (c) 2006, Alexander Neundorf, 
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+MACRO (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage)
+
+   STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" insource)
+   IF(insource)
+      MESSAGE(FATAL_ERROR "${_errorMessage}")
+   ENDIF(insource)
+
+
+ENDMACRO (MACRO_ENSURE_OUT_OF_SOURCE_BUILD)
diff --git a/cmake/modules/ShowStatus.cmake b/cmake/modules/ShowStatus.cmake
new file mode 100644
index 0000000..ba58962
--- /dev/null
+++ b/cmake/modules/ShowStatus.cmake
@@ -0,0 +1,22 @@
+# Shows status of a option variable
+#
+# usage: SHOW_STATUS(   )
+#
+# Copyright (C) 2007 Bjoern Ricks  
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+MACRO( SHOW_STATUS _name _message )
+	IF( DEFINED ${_name} )
+		IF( ${ARGV2} )
+			MESSAGE( STATUS "${_message}\t\t${${_name}}\t(${${ARGV2}})" )
+		ELSE( ${ARGV2} )
+			MESSAGE( STATUS "${_message}\t\t${${_name}}" )
+		ENDIF( ${ARGV2} )
+	ELSE( DEFINED ${_name} )
+		MESSAGE( STATUS "${_message}\t\tOFF" )
+	ENDIF( DEFINED ${_name})
+ENDMACRO( SHOW_STATUS ) 
diff --git a/cmake/modules/Testing.cmake b/cmake/modules/Testing.cmake
new file mode 100644
index 0000000..f65d8e3
--- /dev/null
+++ b/cmake/modules/Testing.cmake
@@ -0,0 +1,63 @@
+ENABLE_TESTING()
+INCLUDE( CTest )
+
+IF ( CMAKE_COMPILER_IS_GNUCC )
+	SET( CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags" ) 
+	# SET( CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wextra -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -pedantic -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags" )
+	SET( CMAKE_CXX_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags" ) 
+	SET( CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags" )
+	SET( CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags" )
+	SET( CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags" )
+ENDIF ( CMAKE_COMPILER_IS_GNUCC )
+
+MACRO( BUILD_CHECK_TEST _testName _testSource ) 
+
+	if(COMMAND cmake_policy)
+		cmake_policy(SET CMP0003 NEW)
+		## The macro ADD_CHECK_TEST creates false warning.
+		cmake_policy(SET CMP0002 OLD)
+	endif(COMMAND cmake_policy)
+	ADD_EXECUTABLE( ${_testName} ${_testSource} )
+	TARGET_LINK_LIBRARIES( ${_testName} ${ARGN} )
+
+ENDMACRO( BUILD_CHECK_TEST )
+
+MACRO( ADD_CHECK_TEST _testName _testSource ) 
+
+	if(COMMAND cmake_policy)
+		cmake_policy(SET CMP0003 NEW)
+		## The macro ADD_CHECK_TEST creates false warning.
+		cmake_policy(SET CMP0002 OLD)
+	endif(COMMAND cmake_policy)
+	BUILD_CHECK_TEST( ${_testName} ${_testSource} ${ARGN} )
+	#	ADD_EXECUTABLE( ${_testName} ${_testSource} )
+	#	TARGET_LINK_LIBRARIES( ${_testName} ${ARGN} )
+	ADD_TEST( ${_testName} ${CMAKE_CURRENT_BINARY_DIR}/${_testName} )
+
+ENDMACRO( ADD_CHECK_TEST )
+
+MACRO( OSYNC_TESTCASE _testSource _testDest ) 
+
+	if(COMMAND cmake_policy)
+		cmake_policy(SET CMP0003 NEW)
+		## The macro ADD_CHECK_TEST creates false warning.
+		cmake_policy(SET CMP0002 OLD)
+	endif(COMMAND cmake_policy)
+
+	# 1st Argument is the testcase name
+	# 2nd Argument is the executable name
+        # 3rd Argument the testcase name, again, as argument for the executable
+	ADD_TEST( ${_testDest} ${_testSource} ${_testDest} )
+
+ENDMACRO( OSYNC_TESTCASE )
+
+
+MACRO( OSYNC_TESTCASE_DISABLED _testSource _testDest _ticket ) 
+
+	OSYNC_TESTCASE( ${_testSource} ${_testDest} ) 
+	SET( CTEST_CUSTOM_TESTS_IGNORE ${CTEST_CUSTOM_TESTS_IGNORE} "${_testDest}" )
+
+	MESSAGE( STATUS "Testcase \"${_testDest}\" disabled/ignored! ${TICKETURL}${_ticket}" )
+
+ENDMACRO( OSYNC_TESTCASE_DISABLED )
+
diff --git a/cmake/modules/cmake_uninstall.cmake.in b/cmake/modules/cmake_uninstall.cmake.in
new file mode 100644
index 0000000..4bfb0bf
--- /dev/null
+++ b/cmake/modules/cmake_uninstall.cmake.in
@@ -0,0 +1,21 @@
+IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+	MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
+ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+
+FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
+STRING(REGEX REPLACE "\n" ";" files "${files}")
+FOREACH(file ${files})
+	MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
+	IF(EXISTS "$ENV{DESTDIR}${file}")
+		EXEC_PROGRAM(
+			"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
+			OUTPUT_VARIABLE rm_out
+			RETURN_VALUE rm_retval
+		)
+		IF(NOT "${rm_retval}" STREQUAL 0)
+			MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
+		ENDIF(NOT "${rm_retval}" STREQUAL 0)
+	ELSE(EXISTS "$ENV{DESTDIR}${file}")
+		MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
+	ENDIF(EXISTS "$ENV{DESTDIR}${file}")
+ENDFOREACH(file)
diff --git a/doxygen/doxygen.conf b/doxygen/doxygen.conf
new file mode 100644
index 0000000..0ce0eae
--- /dev/null
+++ b/doxygen/doxygen.conf
@@ -0,0 +1,278 @@
+# Doxyfile 1.4.7
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = libwbxml2
+PROJECT_NUMBER         = 0.9.3
+OUTPUT_DIRECTORY       = ../doc
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = NO
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = /Applications/
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_JAVA   = NO
+BUILTIN_STL_SUPPORT    = NO
+DISTRIBUTE_GROUP_DOC   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = YES
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = NO
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = NO
+FILE_VERSION_FILTER    = 
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = ../src \
+                         ../tools \
+                         ./doxygen.h
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.C \
+                         *.CC \
+                         *.C++ \
+                         *.II \
+                         *.I++ \
+                         *.H \
+                         *.HH \
+                         *.H++ \
+                         *.CS \
+                         *.PHP \
+                         *.PHP3 \
+                         *.M \
+                         *.MM \
+                         *.PY
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS              = NO
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = YES
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = WBXML_DECLARE(a)=a \
+                         WBXML_DECLARE_NONSTD(a)=a
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = NO
+HIDE_UNDOC_RELATIONS   = NO
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = NO
+GROUP_GRAPHS           = NO
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = YES
+CALLER_GRAPH           = YES
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = /usr/bin/
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = YES
diff --git a/doxygen/doxygen.h b/doxygen/doxygen.h
new file mode 100644
index 0000000..f926d31
--- /dev/null
+++ b/doxygen/doxygen.h
@@ -0,0 +1,87 @@
+/**  
+ * @defgroup wbxml WBXML Library
+ * Result is libwbxml2
+ */
+ 
+/** 
+ * @defgroup wbxml_base64 WBXML Base64 Functions
+ * @ingroup wbxml
+ */
+
+/** 
+ * @defgroup wbxml_buffers WBXML Buffers
+ * @ingroup wbxml
+ */
+
+/** 
+ * @defgroup wbxml_charset WBXML Charset
+ * @ingroup wbxml
+ */
+
+/** 
+ * @defgroup wbxml_conv WBXML Converters
+ * @ingroup wbxml
+ */
+ 
+/** 
+ * @defgroup wbxml_elt WBXML Element
+ * @ingroup wbxml
+ */
+ 
+/** 
+ * @defgroup wbxml_encoder WBXML Encoder
+ * @ingroup wbxml
+ */
+ 
+/** 
+ * @defgroup wbxml_errors WBXML Error Codes
+ * @ingroup wbxml
+ */
+ 
+/** 
+ * @defgroup wbxml_lists WBXML Lists
+ * @ingroup wbxml
+ */
+ 
+/** 
+ * @defgroup wbxml_log WBXML Log Functions
+ * @ingroup wbxml
+ */
+ 
+/** 
+ * @defgroup wbxml_mem WBXML Memory Wrapper
+ * @ingroup wbxml
+ */
+ 
+/** 
+ * @defgroup wbxml_parser WBXML Parser
+ * @ingroup wbxml
+ */
+ 
+/** 
+ * @defgroup wbxml_tables WBXML Tables
+ * @ingroup wbxml
+ */
+ 
+/** 
+ * @defgroup wbxml_tree WBXML Tree
+ * @ingroup wbxml
+ */
+ 
+/** 
+ * @defgroup wbxml2xml_tool WBXML to XML Converter Tool
+ * Result is wbxml2xml
+ */
+ 
+/** 
+ * @defgroup xml2wbxml_tool XML to WBXML Converter Tool
+ * Result is xml2wbxml
+ */
+ 
+/**
+ * @mainpage WBXML Library Documentation
+ *
+ * 
+ * Use the menu to browse the documentation [ Back to WBXML Library Homepage ] + *
+ */ \ No newline at end of file diff --git a/libwbxml2.pc.cmake b/libwbxml2.pc.cmake new file mode 100644 index 0000000..190b6dd --- /dev/null +++ b/libwbxml2.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@LIBWBXML_EXEC_INSTALL_DIR@ +libdir=@LIBWBXML_LIBRARIES_DIR@ +includedir=@LIBWBXML_INCLUDE_DIR@ + +Name: libwbxml2 +Description: C wbxml library +Version: @LIBWBXML_VERSION@ +Requires: expat >= 2.0 +Libs: -L${libdir} -lwbxml2 +Cflags: -I${includedir} diff --git a/macosx/expat/ascii.h b/macosx/expat/ascii.h new file mode 100644 index 0000000..337e5bb --- /dev/null +++ b/macosx/expat/ascii.h @@ -0,0 +1,85 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#define ASCII_A 0x41 +#define ASCII_B 0x42 +#define ASCII_C 0x43 +#define ASCII_D 0x44 +#define ASCII_E 0x45 +#define ASCII_F 0x46 +#define ASCII_G 0x47 +#define ASCII_H 0x48 +#define ASCII_I 0x49 +#define ASCII_J 0x4A +#define ASCII_K 0x4B +#define ASCII_L 0x4C +#define ASCII_M 0x4D +#define ASCII_N 0x4E +#define ASCII_O 0x4F +#define ASCII_P 0x50 +#define ASCII_Q 0x51 +#define ASCII_R 0x52 +#define ASCII_S 0x53 +#define ASCII_T 0x54 +#define ASCII_U 0x55 +#define ASCII_V 0x56 +#define ASCII_W 0x57 +#define ASCII_X 0x58 +#define ASCII_Y 0x59 +#define ASCII_Z 0x5A + +#define ASCII_a 0x61 +#define ASCII_b 0x62 +#define ASCII_c 0x63 +#define ASCII_d 0x64 +#define ASCII_e 0x65 +#define ASCII_f 0x66 +#define ASCII_g 0x67 +#define ASCII_h 0x68 +#define ASCII_i 0x69 +#define ASCII_j 0x6A +#define ASCII_k 0x6B +#define ASCII_l 0x6C +#define ASCII_m 0x6D +#define ASCII_n 0x6E +#define ASCII_o 0x6F +#define ASCII_p 0x70 +#define ASCII_q 0x71 +#define ASCII_r 0x72 +#define ASCII_s 0x73 +#define ASCII_t 0x74 +#define ASCII_u 0x75 +#define ASCII_v 0x76 +#define ASCII_w 0x77 +#define ASCII_x 0x78 +#define ASCII_y 0x79 +#define ASCII_z 0x7A + +#define ASCII_0 0x30 +#define ASCII_1 0x31 +#define ASCII_2 0x32 +#define ASCII_3 0x33 +#define ASCII_4 0x34 +#define ASCII_5 0x35 +#define ASCII_6 0x36 +#define ASCII_7 0x37 +#define ASCII_8 0x38 +#define ASCII_9 0x39 + +#define ASCII_TAB 0x09 +#define ASCII_SPACE 0x20 +#define ASCII_EXCL 0x21 +#define ASCII_QUOT 0x22 +#define ASCII_AMP 0x26 +#define ASCII_APOS 0x27 +#define ASCII_MINUS 0x2D +#define ASCII_PERIOD 0x2E +#define ASCII_COLON 0x3A +#define ASCII_SEMI 0x3B +#define ASCII_LT 0x3C +#define ASCII_EQUALS 0x3D +#define ASCII_GT 0x3E +#define ASCII_LSQB 0x5B +#define ASCII_RSQB 0x5D +#define ASCII_UNDERSCORE 0x5F diff --git a/macosx/expat/asciitab.h b/macosx/expat/asciitab.h new file mode 100644 index 0000000..79a15c2 --- /dev/null +++ b/macosx/expat/asciitab.h @@ -0,0 +1,36 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, +/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, +/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, +/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, +/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, +/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, +/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, +/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, +/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, +/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, +/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/macosx/expat/expat.h b/macosx/expat/expat.h new file mode 100644 index 0000000..0b70302 --- /dev/null +++ b/macosx/expat/expat.h @@ -0,0 +1,926 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef XmlParse_INCLUDED +#define XmlParse_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include + +#ifndef XMLPARSEAPI +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#ifdef XML_STATIC +#define XMLPARSEAPI(type) type __cdecl +#else +#define XMLPARSEAPI(type) __declspec(dllimport) type __cdecl +#endif +#else +#define XMLPARSEAPI(type) type +#endif +#endif /* not defined XMLPARSEAPI */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (*XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (*XML_AttlistDeclHandler) (void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (*XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + When a namespace is not declared, the name and prefix will be + passed through without expansion. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (*XML_StartElementHandler)(void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (*XML_EndElementHandler)(void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (*XML_CharacterDataHandler)(void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (*XML_ProcessingInstructionHandler)(void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data); + +typedef void (*XML_StartCdataSectionHandler)(void *userData); +typedef void (*XML_EndCdataSectionHandler)(void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (*XML_DefaultHandler)(void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (*XML_StartDoctypeDeclHandler)(void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (*XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (*XML_EntityDeclHandler) (void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (*XML_UnparsedEntityDeclHandler)(void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (*XML_NotationDeclHandler)(void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (*XML_StartNamespaceDeclHandler)(void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (*XML_EndNamespaceDeclHandler)(void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (*XML_NotStandaloneHandler)(void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (*XML_SkippedEntityHandler)(void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (*convert)(void *data, const char *s); + void (*release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + The XML_Status enum gives the possible return values for the + XML_Parse and XML_ParseBuffer functions. Though the return values + for these functions has always been described as a Boolean value, + the implementation, at least for the 1.95.x series, has always + returned exactly one of these values. The preprocessor #defines + are included so this stanza can be added to code that still needs + to support older versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1 +#define XML_STATUS_OK XML_STATUS_OK +}; + +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of + the first of the sequence of characters that generated the event. + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(long) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 1 +#define XML_MINOR_VERSION 95 +#define XML_MICRO_VERSION 6 + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlParse_INCLUDED */ diff --git a/macosx/expat/expat_config.h b/macosx/expat/expat_config.h new file mode 100644 index 0000000..da5016d --- /dev/null +++ b/macosx/expat/expat_config.h @@ -0,0 +1,90 @@ +/* expat_config.h. Generated by configure. */ +/* expat_config.h.in. Generated from configure.in by autoheader. */ + +/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ +#define BYTEORDER 4321 + +/* Define to 1 if you have the `bcopy' function. */ +#define HAVE_BCOPY 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `getpagesize' function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "expat-bugs@mail.libexpat.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "expat" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "expat 1.95.5" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "expat" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.95.5" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* whether byteorder is bigendian */ +#define WORDS_BIGENDIAN 1 + +/* Define to specify how much context to retain around the current parse + point. */ +#define XML_CONTEXT_BYTES 1024 + +/* Define to make parameter entity parsing functionality available. */ +#define XML_DTD 1 + +/* Define to make XML Namespaces functionality available. */ +#define XML_NS 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `long' if does not define. */ +/* #undef off_t */ + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ diff --git a/macosx/expat/iasciitab.h b/macosx/expat/iasciitab.h new file mode 100644 index 0000000..24a1d5c --- /dev/null +++ b/macosx/expat/iasciitab.h @@ -0,0 +1,37 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, +/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, +/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, +/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, +/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, +/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, +/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, +/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, +/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, +/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, +/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/macosx/expat/internal.h b/macosx/expat/internal.h new file mode 100644 index 0000000..1bf6baa --- /dev/null +++ b/macosx/expat/internal.h @@ -0,0 +1,73 @@ +/* internal.h + + Internal definitions used by Expat. This is not needed to compile + client code. + + The following calling convention macros are defined for frequently + called functions: + + FASTCALL - Used for those internal functions that have a simple + body and a low number of arguments and local variables. + + PTRCALL - Used for functions called though function pointers. + + PTRFASTCALL - Like PTRCALL, but for low number of arguments. + + inline - Used for selected internal functions for which inlining + may improve performance on some platforms. + + Note: Use of these macros is based on judgement, not hard rules, + and therefore subject to change. +*/ + +#if defined(__GNUC__) +/* Instability reported with egcs on a RedHat Linux 7.3. + Let's comment it out: + #define FASTCALL __attribute__((stdcall, regparm(3))) + and let's try this: +*/ +#define FASTCALL __attribute__((regparm(3))) +#define PTRCALL +#define PTRFASTCALL __attribute__((regparm(3))) + +#elif defined(WIN32) +/* Using __fastcall seems to have an unexpected negative effect under + MS VC++, especially for function pointers, so we won't use it for + now on that platform. It may be reconsidered for a future release + if it can be made more effective. + Likely reason: __fastcall on Windows is like stdcall, therefore + the compiler cannot perform stack optimizations for call clusters. +*/ +#define FASTCALL +#define PTRCALL +#define PTRFASTCALL + +#endif + +#ifndef FASTCALL +#define FASTCALL +#endif + +#ifndef PTRCALL +#define PTRCALL +#endif + +#ifndef PTRFASTCALL +#define PTRFASTCALL +#endif + +#ifndef XML_MIN_SIZE +#if !defined(__cplusplus) && !defined(inline) +#ifdef __GNUC__ +#define inline __inline +#endif /* __GNUC__ */ +#endif +#endif /* XML_MIN_SIZE */ + +#ifdef __cplusplus +#define inline inline +#else +#ifndef inline +#define inline +#endif +#endif diff --git a/macosx/expat/latin1tab.h b/macosx/expat/latin1tab.h new file mode 100644 index 0000000..53c25d7 --- /dev/null +++ b/macosx/expat/latin1tab.h @@ -0,0 +1,36 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, +/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, +/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, +/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, diff --git a/macosx/expat/nametab.h b/macosx/expat/nametab.h new file mode 100644 index 0000000..b05e62c --- /dev/null +++ b/macosx/expat/nametab.h @@ -0,0 +1,150 @@ +static const unsigned namingBitmap[] = { +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE, +0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, +0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF, +0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, +0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, +0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, +0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, +0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, +0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, +0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000, +0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, +0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, +0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003, +0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, +0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, +0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003, +0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, +0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, +0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003, +0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000, +0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, +0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, +0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB, +0x40000000, 0xF580C900, 0x00000007, 0x02010800, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF, +0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, +0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, +0x00000000, 0x00004C40, 0x00000000, 0x00000000, +0x00000007, 0x00000000, 0x00000000, 0x00000000, +0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, +0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF, +0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000, +0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, +0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, +0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, +0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, +0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, +0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, +0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, +0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, +0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, +0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, +0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF, +0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, +0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, +0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0, +0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, +0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, +0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80, +0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, +0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, +0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, +0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000, +0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, +0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, +0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, +0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF, +}; +static const unsigned char nmstrtPages[] = { +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, +0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, +0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +static const unsigned char namePages[] = { +0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, +0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, +0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, +0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; diff --git a/macosx/expat/utf8tab.h b/macosx/expat/utf8tab.h new file mode 100644 index 0000000..7bb3e77 --- /dev/null +++ b/macosx/expat/utf8tab.h @@ -0,0 +1,37 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + + +/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, +/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, diff --git a/macosx/expat/xmlparse.c b/macosx/expat/xmlparse.c new file mode 100644 index 0000000..6e0fa1f --- /dev/null +++ b/macosx/expat/xmlparse.c @@ -0,0 +1,5702 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#include +#include /* memset(), memcpy() */ + +#ifdef COMPILED_FROM_DSP + +#include "winconfig.h" +#define XMLPARSEAPI(type) type __cdecl +#include "expat.h" +#undef XMLPARSEAPI + +#elif defined(MACOS_CLASSIC) + +#include "macconfig.h" +#include "expat.h" + +#else + +#include + +#ifdef __declspec +#define XMLPARSEAPI(type) type __cdecl +#endif + +#include "expat.h" + +#ifdef __declspec +#undef XMLPARSEAPI +#endif +#endif /* ndef COMPILED_FROM_DSP */ + +#ifdef XML_UNICODE +#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX +#define XmlConvert XmlUtf16Convert +#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding +#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS +#define XmlEncode XmlUtf16Encode +#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1)) +typedef unsigned short ICHAR; +#else +#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX +#define XmlConvert XmlUtf8Convert +#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding +#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS +#define XmlEncode XmlUtf8Encode +#define MUST_CONVERT(enc, s) (!(enc)->isUtf8) +typedef char ICHAR; +#endif + + +#ifndef XML_NS + +#define XmlInitEncodingNS XmlInitEncoding +#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding +#undef XmlGetInternalEncodingNS +#define XmlGetInternalEncodingNS XmlGetInternalEncoding +#define XmlParseXmlDeclNS XmlParseXmlDecl + +#endif + +#ifdef XML_UNICODE + +#ifdef XML_UNICODE_WCHAR_T +#define XML_T(x) (const wchar_t)x +#define XML_L(x) L ## x +#else +#define XML_T(x) (const unsigned short)x +#define XML_L(x) x +#endif + +#else + +#define XML_T(x) x +#define XML_L(x) x + +#endif + +/* Round up n to be a multiple of sz, where sz is a power of 2. */ +#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) + +/* Handle the case where memmove() doesn't exist. */ +#ifndef HAVE_MEMMOVE +#ifdef HAVE_BCOPY +#define memmove(d,s,l) bcopy((s),(d),(l)) +#else +#error memmove does not exist on this platform, nor is a substitute available +#endif /* HAVE_BCOPY */ +#endif /* HAVE_MEMMOVE */ + +#include "internal.h" +#include "xmltok.h" +#include "xmlrole.h" + +typedef const XML_Char *KEY; + +typedef struct { + KEY name; +} NAMED; + +typedef struct { + NAMED **v; + size_t size; + size_t used; + size_t usedLim; + const XML_Memory_Handling_Suite *mem; +} HASH_TABLE; + +typedef struct { + NAMED **p; + NAMED **end; +} HASH_TABLE_ITER; + +#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ +#define INIT_DATA_BUF_SIZE 1024 +#define INIT_ATTS_SIZE 16 +#define INIT_BLOCK_SIZE 1024 +#define INIT_BUFFER_SIZE 1024 + +#define EXPAND_SPARE 24 + +typedef struct binding { + struct prefix *prefix; + struct binding *nextTagBinding; + struct binding *prevPrefixBinding; + const struct attribute_id *attId; + XML_Char *uri; + int uriLen; + int uriAlloc; +} BINDING; + +typedef struct prefix { + const XML_Char *name; + BINDING *binding; +} PREFIX; + +typedef struct { + const XML_Char *str; + const XML_Char *localPart; + const XML_Char *prefix; + int strLen; + int uriLen; + int prefixLen; +} TAG_NAME; + +/* TAG represents an open element. + The name of the element is stored in both the document and API + encodings. The memory buffer 'buf' is a separately-allocated + memory area which stores the name. During the XML_Parse()/ + XMLParseBuffer() when the element is open, the memory for the 'raw' + version of the name (in the document encoding) is shared with the + document buffer. If the element is open across calls to + XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to + contain the 'raw' name as well. + + A parser re-uses these structures, maintaining a list of allocated + TAG objects in a free list. +*/ +typedef struct tag { + struct tag *parent; /* parent of this element */ + const char *rawName; /* tagName in the original encoding */ + int rawNameLength; + TAG_NAME name; /* tagName in the API encoding */ + char *buf; /* buffer for name components */ + char *bufEnd; /* end of the buffer */ + BINDING *bindings; +} TAG; + +typedef struct { + const XML_Char *name; + const XML_Char *textPtr; + int textLen; + const XML_Char *systemId; + const XML_Char *base; + const XML_Char *publicId; + const XML_Char *notation; + XML_Bool open; + XML_Bool is_param; + XML_Bool is_internal; /* true if declared in internal subset outside PE */ +} ENTITY; + +typedef struct { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + const XML_Char * name; + int firstchild; + int lastchild; + int childcnt; + int nextsib; +} CONTENT_SCAFFOLD; + +#define INIT_SCAFFOLD_ELEMENTS 32 + +typedef struct block { + struct block *next; + int size; + XML_Char s[1]; +} BLOCK; + +typedef struct { + BLOCK *blocks; + BLOCK *freeBlocks; + const XML_Char *end; + XML_Char *ptr; + XML_Char *start; + const XML_Memory_Handling_Suite *mem; +} STRING_POOL; + +/* The XML_Char before the name is used to determine whether + an attribute has been specified. */ +typedef struct attribute_id { + XML_Char *name; + PREFIX *prefix; + XML_Bool maybeTokenized; + XML_Bool xmlns; +} ATTRIBUTE_ID; + +typedef struct { + const ATTRIBUTE_ID *id; + XML_Bool isCdata; + const XML_Char *value; +} DEFAULT_ATTRIBUTE; + +typedef struct { + const XML_Char *name; + PREFIX *prefix; + const ATTRIBUTE_ID *idAtt; + int nDefaultAtts; + int allocDefaultAtts; + DEFAULT_ATTRIBUTE *defaultAtts; +} ELEMENT_TYPE; + +typedef struct { + HASH_TABLE generalEntities; + HASH_TABLE elementTypes; + HASH_TABLE attributeIds; + HASH_TABLE prefixes; + STRING_POOL pool; + STRING_POOL entityValuePool; + /* false once a parameter entity reference has been skipped */ + XML_Bool keepProcessing; + /* true once an internal or external PE reference has been encountered; + this includes the reference to an external subset */ + XML_Bool hasParamEntityRefs; + XML_Bool standalone; +#ifdef XML_DTD + /* indicates if external PE has been read */ + XML_Bool paramEntityRead; + HASH_TABLE paramEntities; +#endif /* XML_DTD */ + PREFIX defaultPrefix; + /* === scaffolding for building content model === */ + XML_Bool in_eldecl; + CONTENT_SCAFFOLD *scaffold; + unsigned contentStringLen; + unsigned scaffSize; + unsigned scaffCount; + int scaffLevel; + int *scaffIndex; +} DTD; + +typedef struct open_internal_entity { + const char *internalEventPtr; + const char *internalEventEndPtr; + struct open_internal_entity *next; + ENTITY *entity; +} OPEN_INTERNAL_ENTITY; + +typedef enum XML_Error PTRCALL Processor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr); + +static Processor prologProcessor; +static Processor prologInitProcessor; +static Processor contentProcessor; +static Processor cdataSectionProcessor; +#ifdef XML_DTD +static Processor ignoreSectionProcessor; +static Processor externalParEntProcessor; +static Processor externalParEntInitProcessor; +static Processor entityValueProcessor; +static Processor entityValueInitProcessor; +#endif /* XML_DTD */ +static Processor epilogProcessor; +static Processor errorProcessor; +static Processor externalEntityInitProcessor; +static Processor externalEntityInitProcessor2; +static Processor externalEntityInitProcessor3; +static Processor externalEntityContentProcessor; + +static enum XML_Error +handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); +static enum XML_Error +processXmlDecl(XML_Parser parser, int isGeneralTextEntity, + const char *, const char *); +static enum XML_Error +initializeEncoding(XML_Parser parser); +static enum XML_Error +doProlog(XML_Parser parser, const ENCODING *enc, const char *s, + const char *end, int tok, const char *next, const char **nextPtr); +static enum XML_Error +processInternalParamEntity(XML_Parser parser, ENTITY *entity); +static enum XML_Error +doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, + const char *start, const char *end, const char **endPtr); +static enum XML_Error +doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, + const char *end, const char **nextPtr); +#ifdef XML_DTD +static enum XML_Error +doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, + const char *end, const char **nextPtr); +#endif /* XML_DTD */ + +static enum XML_Error +storeAtts(XML_Parser parser, const ENCODING *, const char *s, + TAG_NAME *tagNamePtr, BINDING **bindingsPtr); +static enum XML_Error +addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, + const XML_Char *uri, BINDING **bindingsPtr); +static int +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, + XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue, + XML_Parser parser); +static enum XML_Error +storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, + const char *, const char *, STRING_POOL *); +static enum XML_Error +appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, + const char *, const char *, STRING_POOL *); +static ATTRIBUTE_ID * +getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, + const char *end); +static int +setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); +static enum XML_Error +storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, + const char *end); +static int +reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end); +static int +reportComment(XML_Parser parser, const ENCODING *enc, const char *start, + const char *end); +static void +reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, + const char *end); + +static const XML_Char * getContext(XML_Parser parser); +static XML_Bool +setContext(XML_Parser parser, const XML_Char *context); + +static void FASTCALL normalizePublicId(XML_Char *s); + +static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms); +/* do not call if parentParser != NULL */ +static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); +static void +dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms); +static int +dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms); +static int +copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); + +static NAMED * +lookup(HASH_TABLE *table, KEY name, size_t createSize); +static void FASTCALL +hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms); +static void FASTCALL hashTableClear(HASH_TABLE *); +static void FASTCALL hashTableDestroy(HASH_TABLE *); +static void FASTCALL +hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); +static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *); + +static void FASTCALL +poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms); +static void FASTCALL poolClear(STRING_POOL *); +static void FASTCALL poolDestroy(STRING_POOL *); +static XML_Char * +poolAppend(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end); +static XML_Char * +poolStoreString(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end); +static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); +static const XML_Char * FASTCALL +poolCopyString(STRING_POOL *pool, const XML_Char *s); +static const XML_Char * +poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); +static const XML_Char * FASTCALL +poolAppendString(STRING_POOL *pool, const XML_Char *s); + +static int FASTCALL nextScaffoldPart(XML_Parser parser); +static XML_Content * build_model(XML_Parser parser); +static ELEMENT_TYPE * +getElementType(XML_Parser parser, const ENCODING *enc, + const char *ptr, const char *end); + +static XML_Parser +parserCreate(const XML_Char *encodingName, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *nameSep, + DTD *dtd); +static void +parserInit(XML_Parser parser, const XML_Char *encodingName); + +#define poolStart(pool) ((pool)->start) +#define poolEnd(pool) ((pool)->ptr) +#define poolLength(pool) ((pool)->ptr - (pool)->start) +#define poolChop(pool) ((void)--(pool->ptr)) +#define poolLastChar(pool) (((pool)->ptr)[-1]) +#define poolDiscard(pool) ((pool)->ptr = (pool)->start) +#define poolFinish(pool) ((pool)->start = (pool)->ptr) +#define poolAppendChar(pool, c) \ + (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ + ? 0 \ + : ((*((pool)->ptr)++ = c), 1)) + +struct XML_ParserStruct { + /* The first member must be userData so that the XML_GetUserData + macro works. */ + void *m_userData; + void *m_handlerArg; + char *m_buffer; + const XML_Memory_Handling_Suite m_mem; + /* first character to be parsed */ + const char *m_bufferPtr; + /* past last character to be parsed */ + char *m_bufferEnd; + /* allocated end of buffer */ + const char *m_bufferLim; + long m_parseEndByteIndex; + const char *m_parseEndPtr; + XML_Char *m_dataBuf; + XML_Char *m_dataBufEnd; + XML_StartElementHandler m_startElementHandler; + XML_EndElementHandler m_endElementHandler; + XML_CharacterDataHandler m_characterDataHandler; + XML_ProcessingInstructionHandler m_processingInstructionHandler; + XML_CommentHandler m_commentHandler; + XML_StartCdataSectionHandler m_startCdataSectionHandler; + XML_EndCdataSectionHandler m_endCdataSectionHandler; + XML_DefaultHandler m_defaultHandler; + XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; + XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; + XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; + XML_NotationDeclHandler m_notationDeclHandler; + XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; + XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; + XML_NotStandaloneHandler m_notStandaloneHandler; + XML_ExternalEntityRefHandler m_externalEntityRefHandler; + XML_Parser m_externalEntityRefHandlerArg; + XML_SkippedEntityHandler m_skippedEntityHandler; + XML_UnknownEncodingHandler m_unknownEncodingHandler; + XML_ElementDeclHandler m_elementDeclHandler; + XML_AttlistDeclHandler m_attlistDeclHandler; + XML_EntityDeclHandler m_entityDeclHandler; + XML_XmlDeclHandler m_xmlDeclHandler; + const ENCODING *m_encoding; + INIT_ENCODING m_initEncoding; + const ENCODING *m_internalEncoding; + const XML_Char *m_protocolEncodingName; + XML_Bool m_ns; + XML_Bool m_ns_triplets; + void *m_unknownEncodingMem; + void *m_unknownEncodingData; + void *m_unknownEncodingHandlerData; + void (*m_unknownEncodingRelease)(void *); + PROLOG_STATE m_prologState; + Processor *m_processor; + enum XML_Error m_errorCode; + const char *m_eventPtr; + const char *m_eventEndPtr; + const char *m_positionPtr; + OPEN_INTERNAL_ENTITY *m_openInternalEntities; + XML_Bool m_defaultExpandInternalEntities; + int m_tagLevel; + ENTITY *m_declEntity; + const XML_Char *m_doctypeName; + const XML_Char *m_doctypeSysid; + const XML_Char *m_doctypePubid; + const XML_Char *m_declAttributeType; + const XML_Char *m_declNotationName; + const XML_Char *m_declNotationPublicId; + ELEMENT_TYPE *m_declElementType; + ATTRIBUTE_ID *m_declAttributeId; + XML_Bool m_declAttributeIsCdata; + XML_Bool m_declAttributeIsId; + DTD *m_dtd; + const XML_Char *m_curBase; + TAG *m_tagStack; + TAG *m_freeTagList; + BINDING *m_inheritedBindings; + BINDING *m_freeBindingList; + int m_attsSize; + int m_nSpecifiedAtts; + int m_idAttIndex; + ATTRIBUTE *m_atts; + POSITION m_position; + STRING_POOL m_tempPool; + STRING_POOL m_temp2Pool; + char *m_groupConnector; + unsigned m_groupSize; + XML_Char m_namespaceSeparator; + XML_Parser m_parentParser; +#ifdef XML_DTD + XML_Bool m_isParamEntity; + XML_Bool m_useForeignDTD; + enum XML_ParamEntityParsing m_paramEntityParsing; +#endif +}; + +#define MALLOC(s) (parser->m_mem.malloc_fcn((s))) +#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s))) +#define FREE(p) (parser->m_mem.free_fcn((p))) + +#define userData (parser->m_userData) +#define handlerArg (parser->m_handlerArg) +#define startElementHandler (parser->m_startElementHandler) +#define endElementHandler (parser->m_endElementHandler) +#define characterDataHandler (parser->m_characterDataHandler) +#define processingInstructionHandler \ + (parser->m_processingInstructionHandler) +#define commentHandler (parser->m_commentHandler) +#define startCdataSectionHandler \ + (parser->m_startCdataSectionHandler) +#define endCdataSectionHandler (parser->m_endCdataSectionHandler) +#define defaultHandler (parser->m_defaultHandler) +#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler) +#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler) +#define unparsedEntityDeclHandler \ + (parser->m_unparsedEntityDeclHandler) +#define notationDeclHandler (parser->m_notationDeclHandler) +#define startNamespaceDeclHandler \ + (parser->m_startNamespaceDeclHandler) +#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler) +#define notStandaloneHandler (parser->m_notStandaloneHandler) +#define externalEntityRefHandler \ + (parser->m_externalEntityRefHandler) +#define externalEntityRefHandlerArg \ + (parser->m_externalEntityRefHandlerArg) +#define internalEntityRefHandler \ + (parser->m_internalEntityRefHandler) +#define skippedEntityHandler (parser->m_skippedEntityHandler) +#define unknownEncodingHandler (parser->m_unknownEncodingHandler) +#define elementDeclHandler (parser->m_elementDeclHandler) +#define attlistDeclHandler (parser->m_attlistDeclHandler) +#define entityDeclHandler (parser->m_entityDeclHandler) +#define xmlDeclHandler (parser->m_xmlDeclHandler) +#define encoding (parser->m_encoding) +#define initEncoding (parser->m_initEncoding) +#define internalEncoding (parser->m_internalEncoding) +#define unknownEncodingMem (parser->m_unknownEncodingMem) +#define unknownEncodingData (parser->m_unknownEncodingData) +#define unknownEncodingHandlerData \ + (parser->m_unknownEncodingHandlerData) +#define unknownEncodingRelease (parser->m_unknownEncodingRelease) +#define protocolEncodingName (parser->m_protocolEncodingName) +#define ns (parser->m_ns) +#define ns_triplets (parser->m_ns_triplets) +#define prologState (parser->m_prologState) +#define processor (parser->m_processor) +#define errorCode (parser->m_errorCode) +#define eventPtr (parser->m_eventPtr) +#define eventEndPtr (parser->m_eventEndPtr) +#define positionPtr (parser->m_positionPtr) +#define position (parser->m_position) +#define openInternalEntities (parser->m_openInternalEntities) +#define defaultExpandInternalEntities \ + (parser->m_defaultExpandInternalEntities) +#define tagLevel (parser->m_tagLevel) +#define buffer (parser->m_buffer) +#define bufferPtr (parser->m_bufferPtr) +#define bufferEnd (parser->m_bufferEnd) +#define parseEndByteIndex (parser->m_parseEndByteIndex) +#define parseEndPtr (parser->m_parseEndPtr) +#define bufferLim (parser->m_bufferLim) +#define dataBuf (parser->m_dataBuf) +#define dataBufEnd (parser->m_dataBufEnd) +#define _dtd (parser->m_dtd) +#define curBase (parser->m_curBase) +#define declEntity (parser->m_declEntity) +#define doctypeName (parser->m_doctypeName) +#define doctypeSysid (parser->m_doctypeSysid) +#define doctypePubid (parser->m_doctypePubid) +#define declAttributeType (parser->m_declAttributeType) +#define declNotationName (parser->m_declNotationName) +#define declNotationPublicId (parser->m_declNotationPublicId) +#define declElementType (parser->m_declElementType) +#define declAttributeId (parser->m_declAttributeId) +#define declAttributeIsCdata (parser->m_declAttributeIsCdata) +#define declAttributeIsId (parser->m_declAttributeIsId) +#define freeTagList (parser->m_freeTagList) +#define freeBindingList (parser->m_freeBindingList) +#define inheritedBindings (parser->m_inheritedBindings) +#define tagStack (parser->m_tagStack) +#define atts (parser->m_atts) +#define attsSize (parser->m_attsSize) +#define nSpecifiedAtts (parser->m_nSpecifiedAtts) +#define idAttIndex (parser->m_idAttIndex) +#define tempPool (parser->m_tempPool) +#define temp2Pool (parser->m_temp2Pool) +#define groupConnector (parser->m_groupConnector) +#define groupSize (parser->m_groupSize) +#define namespaceSeparator (parser->m_namespaceSeparator) +#define parentParser (parser->m_parentParser) +#ifdef XML_DTD +#define isParamEntity (parser->m_isParamEntity) +#define useForeignDTD (parser->m_useForeignDTD) +#define paramEntityParsing (parser->m_paramEntityParsing) +#endif /* XML_DTD */ + +#define parsing \ + (parentParser \ + ? \ + (isParamEntity \ + ? \ + (processor != externalParEntInitProcessor) \ + : \ + (processor != externalEntityInitProcessor)) \ + : \ + (processor != prologInitProcessor)) + +XML_Parser +XML_ParserCreate(const XML_Char *encodingName) +{ + return XML_ParserCreate_MM(encodingName, NULL, NULL); +} + +XML_Parser +XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) +{ + XML_Char tmp[2]; + *tmp = nsSep; + return XML_ParserCreate_MM(encodingName, NULL, tmp); +} + +static const XML_Char implicitContext[] = { + 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/', + 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/', + 'X', 'M', 'L', '/', '1', '9', '9', '8', '/', + 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0' +}; + +XML_Parser +XML_ParserCreate_MM(const XML_Char *encodingName, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *nameSep) +{ + XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL); + if (parser != NULL && ns) { + /* implicit context only set for root parser, since child + parsers (i.e. external entity parsers) will inherit it + */ + if (!setContext(parser, implicitContext)) { + XML_ParserFree(parser); + return NULL; + } + } + return parser; +} + +static XML_Parser +parserCreate(const XML_Char *encodingName, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *nameSep, + DTD *dtd) +{ + XML_Parser parser; + + if (memsuite) { + XML_Memory_Handling_Suite *mtemp; + parser = (XML_Parser) + memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); + if (parser != NULL) { + mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); + mtemp->malloc_fcn = memsuite->malloc_fcn; + mtemp->realloc_fcn = memsuite->realloc_fcn; + mtemp->free_fcn = memsuite->free_fcn; + } + } + else { + XML_Memory_Handling_Suite *mtemp; + parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); + if (parser != NULL) { + mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); + mtemp->malloc_fcn = malloc; + mtemp->realloc_fcn = realloc; + mtemp->free_fcn = free; + } + } + + if (!parser) + return parser; + + buffer = NULL; + bufferLim = NULL; + + attsSize = INIT_ATTS_SIZE; + atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE)); + if (atts == NULL) { + FREE(parser); + return NULL; + } + dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); + if (dataBuf == NULL) { + FREE(atts); + FREE(parser); + return NULL; + } + dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; + + if (dtd) + _dtd = dtd; + else { + _dtd = dtdCreate(&parser->m_mem); + if (_dtd == NULL) { + FREE(dataBuf); + FREE(atts); + FREE(parser); + return NULL; + } + } + + freeBindingList = NULL; + freeTagList = NULL; + + groupSize = 0; + groupConnector = NULL; + + unknownEncodingHandler = NULL; + unknownEncodingHandlerData = NULL; + + namespaceSeparator = '!'; + ns = XML_FALSE; + ns_triplets = XML_FALSE; + + poolInit(&tempPool, &(parser->m_mem)); + poolInit(&temp2Pool, &(parser->m_mem)); + parserInit(parser, encodingName); + + if (encodingName && !protocolEncodingName) { + XML_ParserFree(parser); + return NULL; + } + + if (nameSep) { + ns = XML_TRUE; + internalEncoding = XmlGetInternalEncodingNS(); + namespaceSeparator = *nameSep; + } + else { + internalEncoding = XmlGetInternalEncoding(); + } + + return parser; +} + +static void +parserInit(XML_Parser parser, const XML_Char *encodingName) +{ + processor = prologInitProcessor; + XmlPrologStateInit(&prologState); + protocolEncodingName = (encodingName != NULL + ? poolCopyString(&tempPool, encodingName) + : NULL); + curBase = NULL; + XmlInitEncoding(&initEncoding, &encoding, 0); + userData = NULL; + handlerArg = NULL; + startElementHandler = NULL; + endElementHandler = NULL; + characterDataHandler = NULL; + processingInstructionHandler = NULL; + commentHandler = NULL; + startCdataSectionHandler = NULL; + endCdataSectionHandler = NULL; + defaultHandler = NULL; + startDoctypeDeclHandler = NULL; + endDoctypeDeclHandler = NULL; + unparsedEntityDeclHandler = NULL; + notationDeclHandler = NULL; + startNamespaceDeclHandler = NULL; + endNamespaceDeclHandler = NULL; + notStandaloneHandler = NULL; + externalEntityRefHandler = NULL; + externalEntityRefHandlerArg = parser; + skippedEntityHandler = NULL; + elementDeclHandler = NULL; + attlistDeclHandler = NULL; + entityDeclHandler = NULL; + xmlDeclHandler = NULL; + bufferPtr = buffer; + bufferEnd = buffer; + parseEndByteIndex = 0; + parseEndPtr = NULL; + declElementType = NULL; + declAttributeId = NULL; + declEntity = NULL; + doctypeName = NULL; + doctypeSysid = NULL; + doctypePubid = NULL; + declAttributeType = NULL; + declNotationName = NULL; + declNotationPublicId = NULL; + declAttributeIsCdata = XML_FALSE; + declAttributeIsId = XML_FALSE; + memset(&position, 0, sizeof(POSITION)); + errorCode = XML_ERROR_NONE; + eventPtr = NULL; + eventEndPtr = NULL; + positionPtr = NULL; + openInternalEntities = 0; + defaultExpandInternalEntities = XML_TRUE; + tagLevel = 0; + tagStack = NULL; + inheritedBindings = NULL; + nSpecifiedAtts = 0; + unknownEncodingMem = NULL; + unknownEncodingRelease = NULL; + unknownEncodingData = NULL; + parentParser = NULL; +#ifdef XML_DTD + isParamEntity = XML_FALSE; + useForeignDTD = XML_FALSE; + paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; +#endif +} + +/* moves list of bindings to freeBindingList */ +static void FASTCALL +moveToFreeBindingList(XML_Parser parser, BINDING *bindings) +{ + while (bindings) { + BINDING *b = bindings; + bindings = bindings->nextTagBinding; + b->nextTagBinding = freeBindingList; + freeBindingList = b; + } +} + +XML_Bool +XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) +{ + TAG *tStk; + if (parentParser) + return XML_FALSE; + /* move tagStack to freeTagList */ + tStk = tagStack; + while (tStk) { + TAG *tag = tStk; + tStk = tStk->parent; + tag->parent = freeTagList; + moveToFreeBindingList(parser, tag->bindings); + tag->bindings = NULL; + freeTagList = tag; + } + moveToFreeBindingList(parser, inheritedBindings); + if (unknownEncodingMem) + FREE(unknownEncodingMem); + if (unknownEncodingRelease) + unknownEncodingRelease(unknownEncodingData); + poolClear(&tempPool); + poolClear(&temp2Pool); + parserInit(parser, encodingName); + dtdReset(_dtd, &parser->m_mem); + return setContext(parser, implicitContext); +} + +enum XML_Status +XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) +{ + /* Block after XML_Parse()/XML_ParseBuffer() has been called. + XXX There's no way for the caller to determine which of the + XXX possible error cases caused the XML_STATUS_ERROR return. + */ + if (parsing) + return XML_STATUS_ERROR; + if (encodingName == NULL) + protocolEncodingName = NULL; + else { + protocolEncodingName = poolCopyString(&tempPool, encodingName); + if (!protocolEncodingName) + return XML_STATUS_ERROR; + } + return XML_STATUS_OK; +} + +XML_Parser +XML_ExternalEntityParserCreate(XML_Parser oldParser, + const XML_Char *context, + const XML_Char *encodingName) +{ + XML_Parser parser = oldParser; + DTD *newDtd = NULL; + DTD *oldDtd = _dtd; + XML_StartElementHandler oldStartElementHandler = startElementHandler; + XML_EndElementHandler oldEndElementHandler = endElementHandler; + XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; + XML_ProcessingInstructionHandler oldProcessingInstructionHandler + = processingInstructionHandler; + XML_CommentHandler oldCommentHandler = commentHandler; + XML_StartCdataSectionHandler oldStartCdataSectionHandler + = startCdataSectionHandler; + XML_EndCdataSectionHandler oldEndCdataSectionHandler + = endCdataSectionHandler; + XML_DefaultHandler oldDefaultHandler = defaultHandler; + XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler + = unparsedEntityDeclHandler; + XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler; + XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler + = startNamespaceDeclHandler; + XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler + = endNamespaceDeclHandler; + XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; + XML_ExternalEntityRefHandler oldExternalEntityRefHandler + = externalEntityRefHandler; + XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler; + XML_UnknownEncodingHandler oldUnknownEncodingHandler + = unknownEncodingHandler; + XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler; + XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler; + XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler; + XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler; + ELEMENT_TYPE * oldDeclElementType = declElementType; + + void *oldUserData = userData; + void *oldHandlerArg = handlerArg; + XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities; + XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; +#ifdef XML_DTD + enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing; + int oldInEntityValue = prologState.inEntityValue; +#endif + XML_Bool oldns_triplets = ns_triplets; + +#ifdef XML_DTD + if (!context) + newDtd = oldDtd; +#endif /* XML_DTD */ + + /* Note that the magical uses of the pre-processor to make field + access look more like C++ require that `parser' be overwritten + here. This makes this function more painful to follow than it + would be otherwise. + */ + if (ns) { + XML_Char tmp[2]; + *tmp = namespaceSeparator; + parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); + } + else { + parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); + } + + if (!parser) + return NULL; + + startElementHandler = oldStartElementHandler; + endElementHandler = oldEndElementHandler; + characterDataHandler = oldCharacterDataHandler; + processingInstructionHandler = oldProcessingInstructionHandler; + commentHandler = oldCommentHandler; + startCdataSectionHandler = oldStartCdataSectionHandler; + endCdataSectionHandler = oldEndCdataSectionHandler; + defaultHandler = oldDefaultHandler; + unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; + notationDeclHandler = oldNotationDeclHandler; + startNamespaceDeclHandler = oldStartNamespaceDeclHandler; + endNamespaceDeclHandler = oldEndNamespaceDeclHandler; + notStandaloneHandler = oldNotStandaloneHandler; + externalEntityRefHandler = oldExternalEntityRefHandler; + skippedEntityHandler = oldSkippedEntityHandler; + unknownEncodingHandler = oldUnknownEncodingHandler; + elementDeclHandler = oldElementDeclHandler; + attlistDeclHandler = oldAttlistDeclHandler; + entityDeclHandler = oldEntityDeclHandler; + xmlDeclHandler = oldXmlDeclHandler; + declElementType = oldDeclElementType; + userData = oldUserData; + if (oldUserData == oldHandlerArg) + handlerArg = userData; + else + handlerArg = parser; + if (oldExternalEntityRefHandlerArg != oldParser) + externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; + defaultExpandInternalEntities = oldDefaultExpandInternalEntities; + ns_triplets = oldns_triplets; + parentParser = oldParser; +#ifdef XML_DTD + paramEntityParsing = oldParamEntityParsing; + prologState.inEntityValue = oldInEntityValue; + if (context) { +#endif /* XML_DTD */ + if (!dtdCopy(_dtd, oldDtd, &parser->m_mem) + || !setContext(parser, context)) { + XML_ParserFree(parser); + return NULL; + } + processor = externalEntityInitProcessor; +#ifdef XML_DTD + } + else { + /* The DTD instance referenced by _dtd is shared between the document's + root parser and external PE parsers, therefore one does not need to + call setContext. In addition, one also *must* not call setContext, + because this would overwrite existing prefix->binding pointers in + _dtd with ones that get destroyed with the external PE parser. + This would leave those prefixes with dangling pointers. + */ + isParamEntity = XML_TRUE; + XmlPrologStateInitExternalEntity(&prologState); + processor = externalParEntInitProcessor; + } +#endif /* XML_DTD */ + return parser; +} + +static void FASTCALL +destroyBindings(BINDING *bindings, XML_Parser parser) +{ + for (;;) { + BINDING *b = bindings; + if (!b) + break; + bindings = b->nextTagBinding; + FREE(b->uri); + FREE(b); + } +} + +void +XML_ParserFree(XML_Parser parser) +{ + for (;;) { + TAG *p; + if (tagStack == NULL) { + if (freeTagList == NULL) + break; + tagStack = freeTagList; + freeTagList = NULL; + } + p = tagStack; + tagStack = tagStack->parent; + FREE(p->buf); + destroyBindings(p->bindings, parser); + FREE(p); + } + destroyBindings(freeBindingList, parser); + destroyBindings(inheritedBindings, parser); + poolDestroy(&tempPool); + poolDestroy(&temp2Pool); +#ifdef XML_DTD + /* external parameter entity parsers share the DTD structure + parser->m_dtd with the root parser, so we must not destroy it + */ + if (!isParamEntity && _dtd) +#else + if (_dtd) +#endif /* XML_DTD */ + dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem); + FREE((void *)atts); + if (groupConnector) + FREE(groupConnector); + if (buffer) + FREE(buffer); + FREE(dataBuf); + if (unknownEncodingMem) + FREE(unknownEncodingMem); + if (unknownEncodingRelease) + unknownEncodingRelease(unknownEncodingData); + FREE(parser); +} + +void +XML_UseParserAsHandlerArg(XML_Parser parser) +{ + handlerArg = parser; +} + +enum XML_Error +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) +{ +#ifdef XML_DTD + /* block after XML_Parse()/XML_ParseBuffer() has been called */ + if (parsing) + return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; + useForeignDTD = useDTD; + return XML_ERROR_NONE; +#else + return XML_ERROR_FEATURE_REQUIRES_XML_DTD; +#endif +} + +void +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) +{ + /* block after XML_Parse()/XML_ParseBuffer() has been called */ + if (parsing) + return; + ns_triplets = do_nst ? XML_TRUE : XML_FALSE; +} + +void +XML_SetUserData(XML_Parser parser, void *p) +{ + if (handlerArg == userData) + handlerArg = userData = p; + else + userData = p; +} + +enum XML_Status +XML_SetBase(XML_Parser parser, const XML_Char *p) +{ + if (p) { + p = poolCopyString(&_dtd->pool, p); + if (!p) + return XML_STATUS_ERROR; + curBase = p; + } + else + curBase = NULL; + return XML_STATUS_OK; +} + +const XML_Char * +XML_GetBase(XML_Parser parser) +{ + return curBase; +} + +int +XML_GetSpecifiedAttributeCount(XML_Parser parser) +{ + return nSpecifiedAtts; +} + +int +XML_GetIdAttributeIndex(XML_Parser parser) +{ + return idAttIndex; +} + +void +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end) +{ + startElementHandler = start; + endElementHandler = end; +} + +void +XML_SetStartElementHandler(XML_Parser parser, + XML_StartElementHandler start) { + startElementHandler = start; +} + +void +XML_SetEndElementHandler(XML_Parser parser, + XML_EndElementHandler end) { + endElementHandler = end; +} + +void +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler) +{ + characterDataHandler = handler; +} + +void +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler) +{ + processingInstructionHandler = handler; +} + +void +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler) +{ + commentHandler = handler; +} + +void +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end) +{ + startCdataSectionHandler = start; + endCdataSectionHandler = end; +} + +void +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start) { + startCdataSectionHandler = start; +} + +void +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end) { + endCdataSectionHandler = end; +} + +void +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler) +{ + defaultHandler = handler; + defaultExpandInternalEntities = XML_FALSE; +} + +void +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler) +{ + defaultHandler = handler; + defaultExpandInternalEntities = XML_TRUE; +} + +void +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end) +{ + startDoctypeDeclHandler = start; + endDoctypeDeclHandler = end; +} + +void +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start) { + startDoctypeDeclHandler = start; +} + +void +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end) { + endDoctypeDeclHandler = end; +} + +void +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler) +{ + unparsedEntityDeclHandler = handler; +} + +void +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler) +{ + notationDeclHandler = handler; +} + +void +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end) +{ + startNamespaceDeclHandler = start; + endNamespaceDeclHandler = end; +} + +void +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start) { + startNamespaceDeclHandler = start; +} + +void +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end) { + endNamespaceDeclHandler = end; +} + +void +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler) +{ + notStandaloneHandler = handler; +} + +void +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler) +{ + externalEntityRefHandler = handler; +} + +void +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) +{ + if (arg) + externalEntityRefHandlerArg = (XML_Parser)arg; + else + externalEntityRefHandlerArg = parser; +} + +void +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler) +{ + skippedEntityHandler = handler; +} + +void +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *data) +{ + unknownEncodingHandler = handler; + unknownEncodingHandlerData = data; +} + +void +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl) +{ + elementDeclHandler = eldecl; +} + +void +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl) +{ + attlistDeclHandler = attdecl; +} + +void +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler) +{ + entityDeclHandler = handler; +} + +void +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler handler) { + xmlDeclHandler = handler; +} + +int +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing peParsing) +{ + /* block after XML_Parse()/XML_ParseBuffer() has been called */ + if (parsing) + return 0; +#ifdef XML_DTD + paramEntityParsing = peParsing; + return 1; +#else + return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; +#endif +} + +enum XML_Status +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) +{ + if (len == 0) { + if (!isFinal) + return XML_STATUS_OK; + positionPtr = bufferPtr; + errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0); + if (errorCode == XML_ERROR_NONE) + return XML_STATUS_OK; + eventEndPtr = eventPtr; + processor = errorProcessor; + return XML_STATUS_ERROR; + } +#ifndef XML_CONTEXT_BYTES + else if (bufferPtr == bufferEnd) { + const char *end; + int nLeftOver; + parseEndByteIndex += len; + positionPtr = s; + if (isFinal) { + errorCode = processor(parser, s, parseEndPtr = s + len, 0); + if (errorCode == XML_ERROR_NONE) + return XML_STATUS_OK; + eventEndPtr = eventPtr; + processor = errorProcessor; + return XML_STATUS_ERROR; + } + errorCode = processor(parser, s, parseEndPtr = s + len, &end); + if (errorCode != XML_ERROR_NONE) { + eventEndPtr = eventPtr; + processor = errorProcessor; + return XML_STATUS_ERROR; + } + XmlUpdatePosition(encoding, positionPtr, end, &position); + positionPtr = end; + nLeftOver = s + len - end; + if (nLeftOver) { + if (buffer == NULL || nLeftOver > bufferLim - buffer) { + /* FIXME avoid integer overflow */ + char *temp; + temp = (buffer == NULL + ? (char *)MALLOC(len * 2) + : (char *)REALLOC(buffer, len * 2)); + if (temp == NULL) { + errorCode = XML_ERROR_NO_MEMORY; + return XML_STATUS_ERROR; + } + buffer = temp; + if (!buffer) { + errorCode = XML_ERROR_NO_MEMORY; + eventPtr = eventEndPtr = NULL; + processor = errorProcessor; + return XML_STATUS_ERROR; + } + bufferLim = buffer + len * 2; + } + memcpy(buffer, end, nLeftOver); + bufferPtr = buffer; + bufferEnd = buffer + nLeftOver; + } + return XML_STATUS_OK; + } +#endif /* not defined XML_CONTEXT_BYTES */ + else { + void *buff = XML_GetBuffer(parser, len); + if (buff == NULL) + return XML_STATUS_ERROR; + else { + memcpy(buff, s, len); + return XML_ParseBuffer(parser, len, isFinal); + } + } +} + +enum XML_Status +XML_ParseBuffer(XML_Parser parser, int len, int isFinal) +{ + const char *start = bufferPtr; + positionPtr = start; + bufferEnd += len; + parseEndByteIndex += len; + errorCode = processor(parser, start, parseEndPtr = bufferEnd, + isFinal ? (const char **)NULL : &bufferPtr); + if (errorCode == XML_ERROR_NONE) { + if (!isFinal) { + XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); + positionPtr = bufferPtr; + } + return XML_STATUS_OK; + } + else { + eventEndPtr = eventPtr; + processor = errorProcessor; + return XML_STATUS_ERROR; + } +} + +void * +XML_GetBuffer(XML_Parser parser, int len) +{ + if (len > bufferLim - bufferEnd) { + /* FIXME avoid integer overflow */ + int neededSize = len + (bufferEnd - bufferPtr); +#ifdef XML_CONTEXT_BYTES + int keep = bufferPtr - buffer; + + if (keep > XML_CONTEXT_BYTES) + keep = XML_CONTEXT_BYTES; + neededSize += keep; +#endif /* defined XML_CONTEXT_BYTES */ + if (neededSize <= bufferLim - buffer) { +#ifdef XML_CONTEXT_BYTES + if (keep < bufferPtr - buffer) { + int offset = (bufferPtr - buffer) - keep; + memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep); + bufferEnd -= offset; + bufferPtr -= offset; + } +#else + memmove(buffer, bufferPtr, bufferEnd - bufferPtr); + bufferEnd = buffer + (bufferEnd - bufferPtr); + bufferPtr = buffer; +#endif /* not defined XML_CONTEXT_BYTES */ + } + else { + char *newBuf; + int bufferSize = bufferLim - bufferPtr; + if (bufferSize == 0) + bufferSize = INIT_BUFFER_SIZE; + do { + bufferSize *= 2; + } while (bufferSize < neededSize); + newBuf = (char *)MALLOC(bufferSize); + if (newBuf == 0) { + errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } + bufferLim = newBuf + bufferSize; +#ifdef XML_CONTEXT_BYTES + if (bufferPtr) { + int keep = bufferPtr - buffer; + if (keep > XML_CONTEXT_BYTES) + keep = XML_CONTEXT_BYTES; + memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep); + FREE(buffer); + buffer = newBuf; + bufferEnd = buffer + (bufferEnd - bufferPtr) + keep; + bufferPtr = buffer + keep; + } + else { + bufferEnd = newBuf + (bufferEnd - bufferPtr); + bufferPtr = buffer = newBuf; + } +#else + if (bufferPtr) { + memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); + FREE(buffer); + } + bufferEnd = newBuf + (bufferEnd - bufferPtr); + bufferPtr = buffer = newBuf; +#endif /* not defined XML_CONTEXT_BYTES */ + } + } + return bufferEnd; +} + +enum XML_Error +XML_GetErrorCode(XML_Parser parser) +{ + return errorCode; +} + +long +XML_GetCurrentByteIndex(XML_Parser parser) +{ + if (eventPtr) + return parseEndByteIndex - (parseEndPtr - eventPtr); + return -1; +} + +int +XML_GetCurrentByteCount(XML_Parser parser) +{ + if (eventEndPtr && eventPtr) + return eventEndPtr - eventPtr; + return 0; +} + +const char * +XML_GetInputContext(XML_Parser parser, int *offset, int *size) +{ +#ifdef XML_CONTEXT_BYTES + if (eventPtr && buffer) { + *offset = eventPtr - buffer; + *size = bufferEnd - buffer; + return buffer; + } +#endif /* defined XML_CONTEXT_BYTES */ + return (char *) 0; +} + +int +XML_GetCurrentLineNumber(XML_Parser parser) +{ + if (eventPtr) { + XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); + positionPtr = eventPtr; + } + return position.lineNumber + 1; +} + +int +XML_GetCurrentColumnNumber(XML_Parser parser) +{ + if (eventPtr) { + XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); + positionPtr = eventPtr; + } + return position.columnNumber; +} + +void +XML_FreeContentModel(XML_Parser parser, XML_Content *model) +{ + FREE(model); +} + +void * +XML_MemMalloc(XML_Parser parser, size_t size) +{ + return MALLOC(size); +} + +void * +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) +{ + return REALLOC(ptr, size); +} + +void +XML_MemFree(XML_Parser parser, void *ptr) +{ + FREE(ptr); +} + +void +XML_DefaultCurrent(XML_Parser parser) +{ + if (defaultHandler) { + if (openInternalEntities) + reportDefault(parser, + internalEncoding, + openInternalEntities->internalEventPtr, + openInternalEntities->internalEventEndPtr); + else + reportDefault(parser, encoding, eventPtr, eventEndPtr); + } +} + +const XML_LChar * +XML_ErrorString(enum XML_Error code) +{ + static const XML_LChar *message[] = { + 0, + XML_L("out of memory"), + XML_L("syntax error"), + XML_L("no element found"), + XML_L("not well-formed (invalid token)"), + XML_L("unclosed token"), + XML_L("partial character"), + XML_L("mismatched tag"), + XML_L("duplicate attribute"), + XML_L("junk after document element"), + XML_L("illegal parameter entity reference"), + XML_L("undefined entity"), + XML_L("recursive entity reference"), + XML_L("asynchronous entity"), + XML_L("reference to invalid character number"), + XML_L("reference to binary entity"), + XML_L("reference to external entity in attribute"), + XML_L("xml declaration not at start of external entity"), + XML_L("unknown encoding"), + XML_L("encoding specified in XML declaration is incorrect"), + XML_L("unclosed CDATA section"), + XML_L("error in processing external entity reference"), + XML_L("document is not standalone"), + XML_L("unexpected parser state - please send a bug report"), + XML_L("entity declared in parameter entity"), + XML_L("requested feature requires XML_DTD support in Expat"), + XML_L("cannot change setting once parsing has begun") + }; + if (code > 0 && code < sizeof(message)/sizeof(message[0])) + return message[code]; + return NULL; +} + +const XML_LChar * +XML_ExpatVersion(void) { + + /* V1 is used to string-ize the version number. However, it would + string-ize the actual version macro *names* unless we get them + substituted before being passed to V1. CPP is defined to expand + a macro, then rescan for more expansions. Thus, we use V2 to expand + the version macros, then CPP will expand the resulting V1() macro + with the correct numerals. */ + /* ### I'm assuming cpp is portable in this respect... */ + +#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c) +#define V2(a,b,c) XML_L("expat_")V1(a,b,c) + + return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); + +#undef V1 +#undef V2 +} + +XML_Expat_Version +XML_ExpatVersionInfo(void) +{ + XML_Expat_Version version; + + version.major = XML_MAJOR_VERSION; + version.minor = XML_MINOR_VERSION; + version.micro = XML_MICRO_VERSION; + + return version; +} + +const XML_Feature * +XML_GetFeatureList(void) +{ + static XML_Feature features[] = { + {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)")}, + {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)")}, +#ifdef XML_UNICODE + {XML_FEATURE_UNICODE, XML_L("XML_UNICODE")}, +#endif +#ifdef XML_UNICODE_WCHAR_T + {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T")}, +#endif +#ifdef XML_DTD + {XML_FEATURE_DTD, XML_L("XML_DTD")}, +#endif +#ifdef XML_CONTEXT_BYTES + {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), + XML_CONTEXT_BYTES}, +#endif +#ifdef XML_MIN_SIZE + {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE")}, +#endif + {XML_FEATURE_END, NULL} + }; + + features[0].value = sizeof(XML_Char); + features[1].value = sizeof(XML_LChar); + return features; +} + +/* Initially tag->rawName always points into the parse buffer; + for those TAG instances opened while the current parse buffer was + processed, and not yet closed, we need to store tag->rawName in a more + permanent location, since the parse buffer is about to be discarded. +*/ +static XML_Bool +storeRawNames(XML_Parser parser) +{ + TAG *tag = tagStack; + while (tag) { + int bufSize; + int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); + char *rawNameBuf = tag->buf + nameLen; + /* Stop if already stored. Since tagStack is a stack, we can stop + at the first entry that has already been copied; everything + below it in the stack is already been accounted for in a + previous call to this function. + */ + if (tag->rawName == rawNameBuf) + break; + /* For re-use purposes we need to ensure that the + size of tag->buf is a multiple of sizeof(XML_Char). + */ + bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); + if (bufSize > tag->bufEnd - tag->buf) { + char *temp = (char *)REALLOC(tag->buf, bufSize); + if (temp == NULL) + return XML_FALSE; + /* if tag->name.str points to tag->buf (only when namespace + processing is off) then we have to update it + */ + if (tag->name.str == (XML_Char *)tag->buf) + tag->name.str = (XML_Char *)temp; + /* if tag->name.localPart is set (when namespace processing is on) + then update it as well, since it will always point into tag->buf + */ + if (tag->name.localPart) + tag->name.localPart = (XML_Char *)temp + (tag->name.localPart - + (XML_Char *)tag->buf); + tag->buf = temp; + tag->bufEnd = temp + bufSize; + rawNameBuf = temp + nameLen; + } + memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); + tag->rawName = rawNameBuf; + tag = tag->parent; + } + return XML_TRUE; +} + +static enum XML_Error PTRCALL +contentProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + enum XML_Error result = + doContent(parser, 0, encoding, start, end, endPtr); + if (result != XML_ERROR_NONE) + return result; + if (!storeRawNames(parser)) + return XML_ERROR_NO_MEMORY; + return result; +} + +static enum XML_Error PTRCALL +externalEntityInitProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + enum XML_Error result = initializeEncoding(parser); + if (result != XML_ERROR_NONE) + return result; + processor = externalEntityInitProcessor2; + return externalEntityInitProcessor2(parser, start, end, endPtr); +} + +static enum XML_Error PTRCALL +externalEntityInitProcessor2(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + const char *next = start; /* XmlContentTok doesn't always set the last arg */ + int tok = XmlContentTok(encoding, start, end, &next); + switch (tok) { + case XML_TOK_BOM: + /* If we are at the end of the buffer, this would cause the next stage, + i.e. externalEntityInitProcessor3, to pass control directly to + doContent (by detecting XML_TOK_NONE) without processing any xml text + declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. + */ + if (next == end && endPtr) { + *endPtr = next; + return XML_ERROR_NONE; + } + start = next; + break; + case XML_TOK_PARTIAL: + if (endPtr) { + *endPtr = start; + return XML_ERROR_NONE; + } + eventPtr = start; + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (endPtr) { + *endPtr = start; + return XML_ERROR_NONE; + } + eventPtr = start; + return XML_ERROR_PARTIAL_CHAR; + } + processor = externalEntityInitProcessor3; + return externalEntityInitProcessor3(parser, start, end, endPtr); +} + +static enum XML_Error PTRCALL +externalEntityInitProcessor3(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + const char *next = start; /* XmlContentTok doesn't always set the last arg */ + int tok = XmlContentTok(encoding, start, end, &next); + switch (tok) { + case XML_TOK_XML_DECL: + { + enum XML_Error result = processXmlDecl(parser, 1, start, next); + if (result != XML_ERROR_NONE) + return result; + start = next; + } + break; + case XML_TOK_PARTIAL: + if (endPtr) { + *endPtr = start; + return XML_ERROR_NONE; + } + eventPtr = start; + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (endPtr) { + *endPtr = start; + return XML_ERROR_NONE; + } + eventPtr = start; + return XML_ERROR_PARTIAL_CHAR; + } + processor = externalEntityContentProcessor; + tagLevel = 1; + return externalEntityContentProcessor(parser, start, end, endPtr); +} + +static enum XML_Error PTRCALL +externalEntityContentProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + enum XML_Error result = + doContent(parser, 1, encoding, start, end, endPtr); + if (result != XML_ERROR_NONE) + return result; + if (!storeRawNames(parser)) + return XML_ERROR_NO_MEMORY; + return result; +} + +static enum XML_Error +doContent(XML_Parser parser, + int startTagLevel, + const ENCODING *enc, + const char *s, + const char *end, + const char **nextPtr) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + const char **eventPP; + const char **eventEndPP; + if (enc == encoding) { + eventPP = &eventPtr; + eventEndPP = &eventEndPtr; + } + else { + eventPP = &(openInternalEntities->internalEventPtr); + eventEndPP = &(openInternalEntities->internalEventEndPtr); + } + *eventPP = s; + for (;;) { + const char *next = s; /* XmlContentTok doesn't always set the last arg */ + int tok = XmlContentTok(enc, s, end, &next); + *eventEndPP = next; + switch (tok) { + case XML_TOK_TRAILING_CR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + *eventEndPP = end; + if (characterDataHandler) { + XML_Char c = 0xA; + characterDataHandler(handlerArg, &c, 1); + } + else if (defaultHandler) + reportDefault(parser, enc, s, end); + if (startTagLevel == 0) + return XML_ERROR_NO_ELEMENTS; + if (tagLevel != startTagLevel) + return XML_ERROR_ASYNC_ENTITY; + return XML_ERROR_NONE; + case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + if (startTagLevel > 0) { + if (tagLevel != startTagLevel) + return XML_ERROR_ASYNC_ENTITY; + return XML_ERROR_NONE; + } + return XML_ERROR_NO_ELEMENTS; + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_ENTITY_REF: + { + const XML_Char *name; + ENTITY *entity; + XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (ch) { + if (characterDataHandler) + characterDataHandler(handlerArg, &ch, 1); + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + name = poolStoreString(&dtd->pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0); + poolDiscard(&dtd->pool); + /* First, determine if a check for an existing declaration is needed; + if yes, check that the entity exists, and that it is internal, + otherwise call the skipped entity or default handler. + */ + if (!dtd->hasParamEntityRefs || dtd->standalone) { + if (!entity) + return XML_ERROR_UNDEFINED_ENTITY; + else if (!entity->is_internal) + return XML_ERROR_ENTITY_DECLARED_IN_PE; + } + else if (!entity) { + if (skippedEntityHandler) + skippedEntityHandler(handlerArg, name, 0); + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + if (entity->open) + return XML_ERROR_RECURSIVE_ENTITY_REF; + if (entity->notation) + return XML_ERROR_BINARY_ENTITY_REF; + if (entity->textPtr) { + enum XML_Error result; + OPEN_INTERNAL_ENTITY openEntity; + if (!defaultExpandInternalEntities) { + if (skippedEntityHandler) + skippedEntityHandler(handlerArg, entity->name, 0); + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + entity->open = XML_TRUE; + openEntity.next = openInternalEntities; + openInternalEntities = &openEntity; + openEntity.entity = entity; + openEntity.internalEventPtr = NULL; + openEntity.internalEventEndPtr = NULL; + result = doContent(parser, + tagLevel, + internalEncoding, + (char *)entity->textPtr, + (char *)(entity->textPtr + entity->textLen), + 0); + entity->open = XML_FALSE; + openInternalEntities = openEntity.next; + if (result) + return result; + } + else if (externalEntityRefHandler) { + const XML_Char *context; + entity->open = XML_TRUE; + context = getContext(parser); + entity->open = XML_FALSE; + if (!context) + return XML_ERROR_NO_MEMORY; + if (!externalEntityRefHandler((XML_Parser)externalEntityRefHandlerArg, + context, + entity->base, + entity->systemId, + entity->publicId)) + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + poolDiscard(&tempPool); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + case XML_TOK_START_TAG_NO_ATTS: + /* fall through */ + case XML_TOK_START_TAG_WITH_ATTS: + { + TAG *tag; + enum XML_Error result; + XML_Char *toPtr; + if (freeTagList) { + tag = freeTagList; + freeTagList = freeTagList->parent; + } + else { + tag = (TAG *)MALLOC(sizeof(TAG)); + if (!tag) + return XML_ERROR_NO_MEMORY; + tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE); + if (!tag->buf) { + FREE(tag); + return XML_ERROR_NO_MEMORY; + } + tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; + } + tag->bindings = NULL; + tag->parent = tagStack; + tagStack = tag; + tag->name.localPart = NULL; + tag->name.prefix = NULL; + tag->rawName = s + enc->minBytesPerChar; + tag->rawNameLength = XmlNameLength(enc, tag->rawName); + ++tagLevel; + { + const char *rawNameEnd = tag->rawName + tag->rawNameLength; + const char *fromPtr = tag->rawName; + toPtr = (XML_Char *)tag->buf; + for (;;) { + int bufSize; + int convLen; + XmlConvert(enc, + &fromPtr, rawNameEnd, + (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); + convLen = toPtr - (XML_Char *)tag->buf; + if (fromPtr == rawNameEnd) { + tag->name.strLen = convLen; + break; + } + bufSize = (tag->bufEnd - tag->buf) << 1; + { + char *temp = (char *)REALLOC(tag->buf, bufSize); + if (temp == NULL) + return XML_ERROR_NO_MEMORY; + tag->buf = temp; + tag->bufEnd = temp + bufSize; + toPtr = (XML_Char *)temp + convLen; + } + } + } + tag->name.str = (XML_Char *)tag->buf; + *toPtr = XML_T('\0'); + result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); + if (result) + return result; + if (startElementHandler) + startElementHandler(handlerArg, tag->name.str, + (const XML_Char **)atts); + else if (defaultHandler) + reportDefault(parser, enc, s, next); + poolClear(&tempPool); + break; + } + case XML_TOK_EMPTY_ELEMENT_NO_ATTS: + /* fall through */ + case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: + { + const char *rawName = s + enc->minBytesPerChar; + enum XML_Error result; + BINDING *bindings = NULL; + XML_Bool noElmHandlers = XML_TRUE; + TAG_NAME name; + name.str = poolStoreString(&tempPool, enc, rawName, + rawName + XmlNameLength(enc, rawName)); + if (!name.str) + return XML_ERROR_NO_MEMORY; + poolFinish(&tempPool); + result = storeAtts(parser, enc, s, &name, &bindings); + if (result) + return result; + poolFinish(&tempPool); + if (startElementHandler) { + startElementHandler(handlerArg, name.str, (const XML_Char **)atts); + noElmHandlers = XML_FALSE; + } + if (endElementHandler) { + if (startElementHandler) + *eventPP = *eventEndPP; + endElementHandler(handlerArg, name.str); + noElmHandlers = XML_FALSE; + } + if (noElmHandlers && defaultHandler) + reportDefault(parser, enc, s, next); + poolClear(&tempPool); + while (bindings) { + BINDING *b = bindings; + if (endNamespaceDeclHandler) + endNamespaceDeclHandler(handlerArg, b->prefix->name); + bindings = bindings->nextTagBinding; + b->nextTagBinding = freeBindingList; + freeBindingList = b; + b->prefix->binding = b->prevPrefixBinding; + } + } + if (tagLevel == 0) + return epilogProcessor(parser, next, end, nextPtr); + break; + case XML_TOK_END_TAG: + if (tagLevel == startTagLevel) + return XML_ERROR_ASYNC_ENTITY; + else { + int len; + const char *rawName; + TAG *tag = tagStack; + tagStack = tag->parent; + tag->parent = freeTagList; + freeTagList = tag; + rawName = s + enc->minBytesPerChar*2; + len = XmlNameLength(enc, rawName); + if (len != tag->rawNameLength + || memcmp(tag->rawName, rawName, len) != 0) { + *eventPP = rawName; + return XML_ERROR_TAG_MISMATCH; + } + --tagLevel; + if (endElementHandler) { + const XML_Char *localPart; + const XML_Char *prefix; + XML_Char *uri; + localPart = tag->name.localPart; + if (ns && localPart) { + /* localPart and prefix may have been overwritten in + tag->name.str, since this points to the binding->uri + buffer which gets re-used; so we have to add them again + */ + uri = (XML_Char *)tag->name.str + tag->name.uriLen; + /* don't need to check for space - already done in storeAtts() */ + while (*localPart) *uri++ = *localPart++; + prefix = (XML_Char *)tag->name.prefix; + if (ns_triplets && prefix) { + *uri++ = namespaceSeparator; + while (*prefix) *uri++ = *prefix++; + } + *uri = XML_T('\0'); + } + endElementHandler(handlerArg, tag->name.str); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + while (tag->bindings) { + BINDING *b = tag->bindings; + if (endNamespaceDeclHandler) + endNamespaceDeclHandler(handlerArg, b->prefix->name); + tag->bindings = tag->bindings->nextTagBinding; + b->nextTagBinding = freeBindingList; + freeBindingList = b; + b->prefix->binding = b->prevPrefixBinding; + } + if (tagLevel == 0) + return epilogProcessor(parser, next, end, nextPtr); + } + break; + case XML_TOK_CHAR_REF: + { + int n = XmlCharRefNumber(enc, s); + if (n < 0) + return XML_ERROR_BAD_CHAR_REF; + if (characterDataHandler) { + XML_Char buf[XML_ENCODE_MAX]; + characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + } + break; + case XML_TOK_XML_DECL: + return XML_ERROR_MISPLACED_XML_PI; + case XML_TOK_DATA_NEWLINE: + if (characterDataHandler) { + XML_Char c = 0xA; + characterDataHandler(handlerArg, &c, 1); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + case XML_TOK_CDATA_SECT_OPEN: + { + enum XML_Error result; + if (startCdataSectionHandler) + startCdataSectionHandler(handlerArg); +#if 0 + /* Suppose you doing a transformation on a document that involves + changing only the character data. You set up a defaultHandler + and a characterDataHandler. The defaultHandler simply copies + characters through. The characterDataHandler does the + transformation and writes the characters out escaping them as + necessary. This case will fail to work if we leave out the + following two lines (because & and < inside CDATA sections will + be incorrectly escaped). + + However, now we have a start/endCdataSectionHandler, so it seems + easier to let the user deal with this. + */ + else if (characterDataHandler) + characterDataHandler(handlerArg, dataBuf, 0); +#endif + else if (defaultHandler) + reportDefault(parser, enc, s, next); + result = doCdataSection(parser, enc, &next, end, nextPtr); + if (!next) { + processor = cdataSectionProcessor; + return result; + } + } + break; + case XML_TOK_TRAILING_RSQB: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + if (characterDataHandler) { + if (MUST_CONVERT(enc, s)) { + ICHAR *dataPtr = (ICHAR *)dataBuf; + XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); + characterDataHandler(handlerArg, dataBuf, + dataPtr - (ICHAR *)dataBuf); + } + else + characterDataHandler(handlerArg, + (XML_Char *)s, + (XML_Char *)end - (XML_Char *)s); + } + else if (defaultHandler) + reportDefault(parser, enc, s, end); + if (startTagLevel == 0) { + *eventPP = end; + return XML_ERROR_NO_ELEMENTS; + } + if (tagLevel != startTagLevel) { + *eventPP = end; + return XML_ERROR_ASYNC_ENTITY; + } + return XML_ERROR_NONE; + case XML_TOK_DATA_CHARS: + if (characterDataHandler) { + if (MUST_CONVERT(enc, s)) { + for (;;) { + ICHAR *dataPtr = (ICHAR *)dataBuf; + XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); + *eventEndPP = s; + characterDataHandler(handlerArg, dataBuf, + dataPtr - (ICHAR *)dataBuf); + if (s == next) + break; + *eventPP = s; + } + } + else + characterDataHandler(handlerArg, + (XML_Char *)s, + (XML_Char *)next - (XML_Char *)s); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + case XML_TOK_PI: + if (!reportProcessingInstruction(parser, enc, s, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_COMMENT: + if (!reportComment(parser, enc, s, next)) + return XML_ERROR_NO_MEMORY; + break; + default: + if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + *eventPP = s = next; + } + /* not reached */ +} + +/* Precondition: all arguments must be non-NULL; + Purpose: + - normalize attributes + - check attributes for well-formedness + - generate namespace aware attribute names (URI, prefix) + - build list of attributes for startElementHandler + - default attributes + - process namespace declarations (check and report them) + - generate namespace aware element name (URI, prefix) +*/ +static enum XML_Error +storeAtts(XML_Parser parser, const ENCODING *enc, + const char *attStr, TAG_NAME *tagNamePtr, + BINDING **bindingsPtr) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + ELEMENT_TYPE *elementType = NULL; + int nDefaultAtts = 0; + const XML_Char **appAtts; /* the attribute list for the application */ + int attIndex = 0; + int prefixLen; + int i; + int n; + XML_Char *uri; + int nPrefixes = 0; + BINDING *binding; + const XML_Char *localPart; + + /* lookup the element type name */ + elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0); + if (!elementType) { + const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); + if (!name) + return XML_ERROR_NO_MEMORY; + elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name, + sizeof(ELEMENT_TYPE)); + if (!elementType) + return XML_ERROR_NO_MEMORY; + if (ns && !setElementTypePrefix(parser, elementType)) + return XML_ERROR_NO_MEMORY; + } + nDefaultAtts = elementType->nDefaultAtts; + + /* get the attributes from the tokenizer */ + n = XmlGetAttributes(enc, attStr, attsSize, atts); + if (n + nDefaultAtts > attsSize) { + int oldAttsSize = attsSize; + ATTRIBUTE *temp; + attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; + temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE)); + if (temp == NULL) + return XML_ERROR_NO_MEMORY; + atts = temp; + if (n > oldAttsSize) + XmlGetAttributes(enc, attStr, n, atts); + } + + appAtts = (const XML_Char **)atts; + for (i = 0; i < n; i++) { + /* add the name and value to the attribute list */ + ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name, + atts[i].name + + XmlNameLength(enc, atts[i].name)); + if (!attId) + return XML_ERROR_NO_MEMORY; + /* detect duplicate attributes */ + if ((attId->name)[-1]) { + if (enc == encoding) + eventPtr = atts[i].name; + return XML_ERROR_DUPLICATE_ATTRIBUTE; + } + (attId->name)[-1] = 1; + appAtts[attIndex++] = attId->name; + if (!atts[i].normalized) { + enum XML_Error result; + XML_Bool isCdata = XML_TRUE; + + /* figure out whether declared as other than CDATA */ + if (attId->maybeTokenized) { + int j; + for (j = 0; j < nDefaultAtts; j++) { + if (attId == elementType->defaultAtts[j].id) { + isCdata = elementType->defaultAtts[j].isCdata; + break; + } + } + } + + /* normalize the attribute value */ + result = storeAttributeValue(parser, enc, isCdata, + atts[i].valuePtr, atts[i].valueEnd, + &tempPool); + if (result) + return result; + appAtts[attIndex] = poolStart(&tempPool); + poolFinish(&tempPool); + } + else { + /* the value did not need normalizing */ + appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, + atts[i].valueEnd); + if (appAtts[attIndex] == 0) + return XML_ERROR_NO_MEMORY; + poolFinish(&tempPool); + } + /* handle prefixed attribute names */ + if (attId->prefix) { + if (attId->xmlns) { + /* deal with namespace declarations here */ + enum XML_Error result = addBinding(parser, attId->prefix, attId, + appAtts[attIndex], bindingsPtr); + if (result) + return result; + --attIndex; + } + else { + /* deal with other prefixed names later */ + attIndex++; + nPrefixes++; + (attId->name)[-1] = 2; + } + } + else + attIndex++; + } + + /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ + nSpecifiedAtts = attIndex; + if (elementType->idAtt && (elementType->idAtt->name)[-1]) { + for (i = 0; i < attIndex; i += 2) + if (appAtts[i] == elementType->idAtt->name) { + idAttIndex = i; + break; + } + } + else + idAttIndex = -1; + + /* do attribute defaulting */ + for (i = 0; i < nDefaultAtts; i++) { + const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; + if (!(da->id->name)[-1] && da->value) { + if (da->id->prefix) { + if (da->id->xmlns) { + enum XML_Error result = addBinding(parser, da->id->prefix, da->id, + da->value, bindingsPtr); + if (result) + return result; + } + else { + (da->id->name)[-1] = 2; + nPrefixes++; + appAtts[attIndex++] = da->id->name; + appAtts[attIndex++] = da->value; + } + } + else { + (da->id->name)[-1] = 1; + appAtts[attIndex++] = da->id->name; + appAtts[attIndex++] = da->value; + } + } + } + appAtts[attIndex] = 0; + + i = 0; + if (nPrefixes) { + /* expand prefixed attribute names */ + for (; i < attIndex; i += 2) { + if (appAtts[i][-1] == 2) { + ATTRIBUTE_ID *id; + ((XML_Char *)(appAtts[i]))[-1] = 0; + id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, appAtts[i], 0); + if (id->prefix->binding) { + int j; + const BINDING *b = id->prefix->binding; + const XML_Char *s = appAtts[i]; + for (j = 0; j < b->uriLen; j++) { + if (!poolAppendChar(&tempPool, b->uri[j])) + return XML_ERROR_NO_MEMORY; + } + while (*s++ != XML_T(':')) + ; + do { + if (!poolAppendChar(&tempPool, *s)) + return XML_ERROR_NO_MEMORY; + } while (*s++); + if (ns_triplets) { + tempPool.ptr[-1] = namespaceSeparator; + s = b->prefix->name; + do { + if (!poolAppendChar(&tempPool, *s)) + return XML_ERROR_NO_MEMORY; + } while (*s++); + } + + appAtts[i] = poolStart(&tempPool); + poolFinish(&tempPool); + } + if (!--nPrefixes) + break; + } + else + ((XML_Char *)(appAtts[i]))[-1] = 0; + } + } + /* clear the flags that say whether attributes were specified */ + for (; i < attIndex; i += 2) + ((XML_Char *)(appAtts[i]))[-1] = 0; + for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) + binding->attId->name[-1] = 0; + + /* expand the element type name */ + if (elementType->prefix) { + binding = elementType->prefix->binding; + if (!binding) + return XML_ERROR_NONE; + localPart = tagNamePtr->str; + while (*localPart++ != XML_T(':')) + ; + } + else if (dtd->defaultPrefix.binding) { + binding = dtd->defaultPrefix.binding; + localPart = tagNamePtr->str; + } + else + return XML_ERROR_NONE; + prefixLen = 0; + if (ns && ns_triplets && binding->prefix->name) { + for (; binding->prefix->name[prefixLen++];) + ; + } + tagNamePtr->localPart = localPart; + tagNamePtr->uriLen = binding->uriLen; + tagNamePtr->prefix = binding->prefix->name; + tagNamePtr->prefixLen = prefixLen; + for (i = 0; localPart[i++];) + ; + n = i + binding->uriLen + prefixLen; + if (n > binding->uriAlloc) { + TAG *p; + uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char)); + if (!uri) + return XML_ERROR_NO_MEMORY; + binding->uriAlloc = n + EXPAND_SPARE; + memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); + for (p = tagStack; p; p = p->parent) + if (p->name.str == binding->uri) + p->name.str = uri; + FREE(binding->uri); + binding->uri = uri; + } + uri = binding->uri + binding->uriLen; + memcpy(uri, localPart, i * sizeof(XML_Char)); + if (prefixLen) { + uri = uri + (i - 1); + if (namespaceSeparator) { *(uri) = namespaceSeparator; } + memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); + } + tagNamePtr->str = binding->uri; + return XML_ERROR_NONE; +} + +/* addBinding() overwrites the value of prefix->binding without checking. + Therefore one must keep track of the old value outside of addBinding(). +*/ +static enum XML_Error +addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, + const XML_Char *uri, BINDING **bindingsPtr) +{ + BINDING *b; + int len; + + /* empty string is only valid when there is no prefix per XML NS 1.0 */ + if (*uri == XML_T('\0') && prefix->name) + return XML_ERROR_SYNTAX; + + for (len = 0; uri[len]; len++) + ; + if (namespaceSeparator) + len++; + if (freeBindingList) { + b = freeBindingList; + if (len > b->uriAlloc) { + XML_Char *temp = (XML_Char *)REALLOC(b->uri, + sizeof(XML_Char) * (len + EXPAND_SPARE)); + if (temp == NULL) + return XML_ERROR_NO_MEMORY; + b->uri = temp; + b->uriAlloc = len + EXPAND_SPARE; + } + freeBindingList = b->nextTagBinding; + } + else { + b = (BINDING *)MALLOC(sizeof(BINDING)); + if (!b) + return XML_ERROR_NO_MEMORY; + b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE)); + if (!b->uri) { + FREE(b); + return XML_ERROR_NO_MEMORY; + } + b->uriAlloc = len + EXPAND_SPARE; + } + b->uriLen = len; + memcpy(b->uri, uri, len * sizeof(XML_Char)); + if (namespaceSeparator) + b->uri[len - 1] = namespaceSeparator; + b->prefix = prefix; + b->attId = attId; + b->prevPrefixBinding = prefix->binding; + if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix) + prefix->binding = NULL; + else + prefix->binding = b; + b->nextTagBinding = *bindingsPtr; + *bindingsPtr = b; + if (startNamespaceDeclHandler) + startNamespaceDeclHandler(handlerArg, prefix->name, + prefix->binding ? uri : 0); + return XML_ERROR_NONE; +} + +/* The idea here is to avoid using stack for each CDATA section when + the whole file is parsed with one call. +*/ +static enum XML_Error PTRCALL +cdataSectionProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + enum XML_Error result = doCdataSection(parser, encoding, &start, + end, endPtr); + if (start) { + if (parentParser) { /* we are parsing an external entity */ + processor = externalEntityContentProcessor; + return externalEntityContentProcessor(parser, start, end, endPtr); + } + else { + processor = contentProcessor; + return contentProcessor(parser, start, end, endPtr); + } + } + return result; +} + +/* startPtr gets set to non-null is the section is closed, and to null if + the section is not yet closed. +*/ +static enum XML_Error +doCdataSection(XML_Parser parser, + const ENCODING *enc, + const char **startPtr, + const char *end, + const char **nextPtr) +{ + const char *s = *startPtr; + const char **eventPP; + const char **eventEndPP; + if (enc == encoding) { + eventPP = &eventPtr; + *eventPP = s; + eventEndPP = &eventEndPtr; + } + else { + eventPP = &(openInternalEntities->internalEventPtr); + eventEndPP = &(openInternalEntities->internalEventEndPtr); + } + *eventPP = s; + *startPtr = NULL; + for (;;) { + const char *next; + int tok = XmlCdataSectionTok(enc, s, end, &next); + *eventEndPP = next; + switch (tok) { + case XML_TOK_CDATA_SECT_CLOSE: + if (endCdataSectionHandler) + endCdataSectionHandler(handlerArg); +#if 0 + /* see comment under XML_TOK_CDATA_SECT_OPEN */ + else if (characterDataHandler) + characterDataHandler(handlerArg, dataBuf, 0); +#endif + else if (defaultHandler) + reportDefault(parser, enc, s, next); + *startPtr = next; + return XML_ERROR_NONE; + case XML_TOK_DATA_NEWLINE: + if (characterDataHandler) { + XML_Char c = 0xA; + characterDataHandler(handlerArg, &c, 1); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + case XML_TOK_DATA_CHARS: + if (characterDataHandler) { + if (MUST_CONVERT(enc, s)) { + for (;;) { + ICHAR *dataPtr = (ICHAR *)dataBuf; + XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); + *eventEndPP = next; + characterDataHandler(handlerArg, dataBuf, + dataPtr - (ICHAR *)dataBuf); + if (s == next) + break; + *eventPP = s; + } + } + else + characterDataHandler(handlerArg, + (XML_Char *)s, + (XML_Char *)next - (XML_Char *)s); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_PARTIAL: + case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_CDATA_SECTION; + default: + *eventPP = next; + return XML_ERROR_UNEXPECTED_STATE; + } + *eventPP = s = next; + } + /* not reached */ +} + +#ifdef XML_DTD + +/* The idea here is to avoid using stack for each IGNORE section when + the whole file is parsed with one call. +*/ +static enum XML_Error PTRCALL +ignoreSectionProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + enum XML_Error result = doIgnoreSection(parser, encoding, &start, + end, endPtr); + if (start) { + processor = prologProcessor; + return prologProcessor(parser, start, end, endPtr); + } + return result; +} + +/* startPtr gets set to non-null is the section is closed, and to null + if the section is not yet closed. +*/ +static enum XML_Error +doIgnoreSection(XML_Parser parser, + const ENCODING *enc, + const char **startPtr, + const char *end, + const char **nextPtr) +{ + const char *next; + int tok; + const char *s = *startPtr; + const char **eventPP; + const char **eventEndPP; + if (enc == encoding) { + eventPP = &eventPtr; + *eventPP = s; + eventEndPP = &eventEndPtr; + } + else { + eventPP = &(openInternalEntities->internalEventPtr); + eventEndPP = &(openInternalEntities->internalEventEndPtr); + } + *eventPP = s; + *startPtr = NULL; + tok = XmlIgnoreSectionTok(enc, s, end, &next); + *eventEndPP = next; + switch (tok) { + case XML_TOK_IGNORE_SECT: + if (defaultHandler) + reportDefault(parser, enc, s, next); + *startPtr = next; + return XML_ERROR_NONE; + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_PARTIAL: + case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ + default: + *eventPP = next; + return XML_ERROR_UNEXPECTED_STATE; + } + /* not reached */ +} + +#endif /* XML_DTD */ + +static enum XML_Error +initializeEncoding(XML_Parser parser) +{ + const char *s; +#ifdef XML_UNICODE + char encodingBuf[128]; + if (!protocolEncodingName) + s = NULL; + else { + int i; + for (i = 0; protocolEncodingName[i]; i++) { + if (i == sizeof(encodingBuf) - 1 + || (protocolEncodingName[i] & ~0x7f) != 0) { + encodingBuf[0] = '\0'; + break; + } + encodingBuf[i] = (char)protocolEncodingName[i]; + } + encodingBuf[i] = '\0'; + s = encodingBuf; + } +#else + s = protocolEncodingName; +#endif + if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) + return XML_ERROR_NONE; + return handleUnknownEncoding(parser, protocolEncodingName); +} + +static enum XML_Error +processXmlDecl(XML_Parser parser, int isGeneralTextEntity, + const char *s, const char *next) +{ + const char *encodingName = NULL; + const XML_Char *storedEncName = NULL; + const ENCODING *newEncoding = NULL; + const char *version = NULL; + const char *versionend; + const XML_Char *storedversion = NULL; + int standalone = -1; + if (!(ns + ? XmlParseXmlDeclNS + : XmlParseXmlDecl)(isGeneralTextEntity, + encoding, + s, + next, + &eventPtr, + &version, + &versionend, + &encodingName, + &newEncoding, + &standalone)) + return XML_ERROR_SYNTAX; + if (!isGeneralTextEntity && standalone == 1) { + _dtd->standalone = XML_TRUE; +#ifdef XML_DTD + if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) + paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; +#endif /* XML_DTD */ + } + if (xmlDeclHandler) { + if (encodingName != NULL) { + storedEncName = poolStoreString(&temp2Pool, + encoding, + encodingName, + encodingName + + XmlNameLength(encoding, encodingName)); + if (!storedEncName) + return XML_ERROR_NO_MEMORY; + poolFinish(&temp2Pool); + } + if (version) { + storedversion = poolStoreString(&temp2Pool, + encoding, + version, + versionend - encoding->minBytesPerChar); + if (!storedversion) + return XML_ERROR_NO_MEMORY; + } + xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone); + } + else if (defaultHandler) + reportDefault(parser, encoding, s, next); + if (protocolEncodingName == NULL) { + if (newEncoding) { + if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { + eventPtr = encodingName; + return XML_ERROR_INCORRECT_ENCODING; + } + encoding = newEncoding; + } + else if (encodingName) { + enum XML_Error result; + if (!storedEncName) { + storedEncName = poolStoreString( + &temp2Pool, encoding, encodingName, + encodingName + XmlNameLength(encoding, encodingName)); + if (!storedEncName) + return XML_ERROR_NO_MEMORY; + } + result = handleUnknownEncoding(parser, storedEncName); + poolClear(&temp2Pool); + if (result == XML_ERROR_UNKNOWN_ENCODING) + eventPtr = encodingName; + return result; + } + } + + if (storedEncName || storedversion) + poolClear(&temp2Pool); + + return XML_ERROR_NONE; +} + +static enum XML_Error +handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) +{ + if (unknownEncodingHandler) { + XML_Encoding info; + int i; + for (i = 0; i < 256; i++) + info.map[i] = -1; + info.convert = NULL; + info.data = NULL; + info.release = NULL; + if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, + &info)) { + ENCODING *enc; + unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding()); + if (!unknownEncodingMem) { + if (info.release) + info.release(info.data); + return XML_ERROR_NO_MEMORY; + } + enc = (ns + ? XmlInitUnknownEncodingNS + : XmlInitUnknownEncoding)(unknownEncodingMem, + info.map, + info.convert, + info.data); + if (enc) { + unknownEncodingData = info.data; + unknownEncodingRelease = info.release; + encoding = enc; + return XML_ERROR_NONE; + } + } + if (info.release != NULL) + info.release(info.data); + } + return XML_ERROR_UNKNOWN_ENCODING; +} + +static enum XML_Error PTRCALL +prologInitProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + enum XML_Error result = initializeEncoding(parser); + if (result != XML_ERROR_NONE) + return result; + processor = prologProcessor; + return prologProcessor(parser, s, end, nextPtr); +} + +#ifdef XML_DTD + +static enum XML_Error PTRCALL +externalParEntInitProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + enum XML_Error result = initializeEncoding(parser); + if (result != XML_ERROR_NONE) + return result; + + /* we know now that XML_Parse(Buffer) has been called, + so we consider the external parameter entity read */ + _dtd->paramEntityRead = XML_TRUE; + + if (prologState.inEntityValue) { + processor = entityValueInitProcessor; + return entityValueInitProcessor(parser, s, end, nextPtr); + } + else { + processor = externalParEntProcessor; + return externalParEntProcessor(parser, s, end, nextPtr); + } +} + +static enum XML_Error PTRCALL +entityValueInitProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + const char *start = s; + const char *next = s; + int tok; + + for (;;) { + tok = XmlPrologTok(encoding, start, end, &next); + if (tok <= 0) { + if (nextPtr != 0 && tok != XML_TOK_INVALID) { + *nextPtr = s; + return XML_ERROR_NONE; + } + switch (tok) { + case XML_TOK_INVALID: + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_NONE: /* start == end */ + default: + break; + } + return storeEntityValue(parser, encoding, s, end); + } + else if (tok == XML_TOK_XML_DECL) { + enum XML_Error result = processXmlDecl(parser, 0, start, next); + if (result != XML_ERROR_NONE) + return result; + if (nextPtr) *nextPtr = next; + /* stop scanning for text declaration - we found one */ + processor = entityValueProcessor; + return entityValueProcessor(parser, next, end, nextPtr); + } + /* If we are at the end of the buffer, this would cause XmlPrologTok to + return XML_TOK_NONE on the next call, which would then cause the + function to exit with *nextPtr set to s - that is what we want for other + tokens, but not for the BOM - we would rather like to skip it; + then, when this routine is entered the next time, XmlPrologTok will + return XML_TOK_INVALID, since the BOM is still in the buffer + */ + else if (tok == XML_TOK_BOM && next == end && nextPtr) { + *nextPtr = next; + return XML_ERROR_NONE; + } + start = next; + } +} + +static enum XML_Error PTRCALL +externalParEntProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + const char *start = s; + const char *next = s; + int tok; + + tok = XmlPrologTok(encoding, start, end, &next); + if (tok <= 0) { + if (nextPtr != 0 && tok != XML_TOK_INVALID) { + *nextPtr = s; + return XML_ERROR_NONE; + } + switch (tok) { + case XML_TOK_INVALID: + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_NONE: /* start == end */ + default: + break; + } + } + /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. + However, when parsing an external subset, doProlog will not accept a BOM + as valid, and report a syntax error, so we have to skip the BOM + */ + else if (tok == XML_TOK_BOM) { + s = next; + tok = XmlPrologTok(encoding, s, end, &next); + } + + processor = prologProcessor; + return doProlog(parser, encoding, s, end, tok, next, nextPtr); +} + +static enum XML_Error PTRCALL +entityValueProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + const char *start = s; + const char *next = s; + const ENCODING *enc = encoding; + int tok; + + for (;;) { + tok = XmlPrologTok(enc, start, end, &next); + if (tok <= 0) { + if (nextPtr != 0 && tok != XML_TOK_INVALID) { + *nextPtr = s; + return XML_ERROR_NONE; + } + switch (tok) { + case XML_TOK_INVALID: + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_NONE: /* start == end */ + default: + break; + } + return storeEntityValue(parser, enc, s, end); + } + start = next; + } +} + +#endif /* XML_DTD */ + +static enum XML_Error PTRCALL +prologProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + const char *next = s; + int tok = XmlPrologTok(encoding, s, end, &next); + return doProlog(parser, encoding, s, end, tok, next, nextPtr); +} + +static enum XML_Error +doProlog(XML_Parser parser, + const ENCODING *enc, + const char *s, + const char *end, + int tok, + const char *next, + const char **nextPtr) +{ +#ifdef XML_DTD + static const XML_Char externalSubsetName[] = { '#' , '\0' }; +#endif /* XML_DTD */ + static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' }; + static const XML_Char atypeID[] = { 'I', 'D', '\0' }; + static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' }; + static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' }; + static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' }; + static const XML_Char atypeENTITIES[] = + { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' }; + static const XML_Char atypeNMTOKEN[] = { + 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' }; + static const XML_Char atypeNMTOKENS[] = { + 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' }; + static const XML_Char notationPrefix[] = { + 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' }; + static const XML_Char enumValueSep[] = { '|', '\0' }; + static const XML_Char enumValueStart[] = { '(', '\0' }; + + DTD * const dtd = _dtd; /* save one level of indirection */ + + const char **eventPP; + const char **eventEndPP; + enum XML_Content_Quant quant; + + if (enc == encoding) { + eventPP = &eventPtr; + eventEndPP = &eventEndPtr; + } + else { + eventPP = &(openInternalEntities->internalEventPtr); + eventEndPP = &(openInternalEntities->internalEventEndPtr); + } + for (;;) { + int role; + XML_Bool handleDefault = XML_TRUE; + *eventPP = s; + *eventEndPP = next; + if (tok <= 0) { + if (nextPtr != 0 && tok != XML_TOK_INVALID) { + *nextPtr = s; + return XML_ERROR_NONE; + } + switch (tok) { + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_NONE: +#ifdef XML_DTD + if (enc != encoding) + return XML_ERROR_NONE; + if (isParamEntity) { + if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) + == XML_ROLE_ERROR) + return XML_ERROR_SYNTAX; + return XML_ERROR_NONE; + } +#endif /* XML_DTD */ + return XML_ERROR_NO_ELEMENTS; + default: + tok = -tok; + next = end; + break; + } + } + role = XmlTokenRole(&prologState, tok, s, next, enc); + switch (role) { + case XML_ROLE_XML_DECL: + { + enum XML_Error result = processXmlDecl(parser, 0, s, next); + if (result != XML_ERROR_NONE) + return result; + enc = encoding; + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_DOCTYPE_NAME: + if (startDoctypeDeclHandler) { + doctypeName = poolStoreString(&tempPool, enc, s, next); + if (!doctypeName) + return XML_ERROR_NO_MEMORY; + poolFinish(&tempPool); + doctypePubid = NULL; + handleDefault = XML_FALSE; + } + doctypeSysid = NULL; /* always initialize to NULL */ + break; + case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: + if (startDoctypeDeclHandler) { + startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid, + doctypePubid, 1); + doctypeName = NULL; + poolClear(&tempPool); + handleDefault = XML_FALSE; + } + break; +#ifdef XML_DTD + case XML_ROLE_TEXT_DECL: + { + enum XML_Error result = processXmlDecl(parser, 1, s, next); + if (result != XML_ERROR_NONE) + return result; + enc = encoding; + handleDefault = XML_FALSE; + } + break; +#endif /* XML_DTD */ + case XML_ROLE_DOCTYPE_PUBLIC_ID: +#ifdef XML_DTD + useForeignDTD = XML_FALSE; +#endif /* XML_DTD */ + dtd->hasParamEntityRefs = XML_TRUE; + if (startDoctypeDeclHandler) { + doctypePubid = poolStoreString(&tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!doctypePubid) + return XML_ERROR_NO_MEMORY; + poolFinish(&tempPool); + handleDefault = XML_FALSE; + } +#ifdef XML_DTD + declEntity = (ENTITY *)lookup(&dtd->paramEntities, + externalSubsetName, + sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; +#endif /* XML_DTD */ + /* fall through */ + case XML_ROLE_ENTITY_PUBLIC_ID: + if (!XmlIsPublicId(enc, s, next, eventPP)) + return XML_ERROR_SYNTAX; + if (dtd->keepProcessing && declEntity) { + XML_Char *tem = poolStoreString(&dtd->pool, + enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!tem) + return XML_ERROR_NO_MEMORY; + normalizePublicId(tem); + declEntity->publicId = tem; + poolFinish(&dtd->pool); + if (entityDeclHandler) + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_DOCTYPE_CLOSE: + if (doctypeName) { + startDoctypeDeclHandler(handlerArg, doctypeName, + doctypeSysid, doctypePubid, 0); + poolClear(&tempPool); + handleDefault = XML_FALSE; + } + /* doctypeSysid will be non-NULL in the case of a previous + XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler + was not set, indicating an external subset + */ +#ifdef XML_DTD + if (doctypeSysid || useForeignDTD) { + dtd->hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */ + if (paramEntityParsing && externalEntityRefHandler) { + ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities, + externalSubsetName, + sizeof(ENTITY)); + if (!entity) + return XML_ERROR_NO_MEMORY; + if (useForeignDTD) + entity->base = curBase; + dtd->paramEntityRead = XML_FALSE; + if (!externalEntityRefHandler(externalEntityRefHandlerArg, + 0, + entity->base, + entity->systemId, + entity->publicId)) + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + if (dtd->paramEntityRead && + !dtd->standalone && + notStandaloneHandler && + !notStandaloneHandler(handlerArg)) + return XML_ERROR_NOT_STANDALONE; + /* end of DTD - no need to update dtd->keepProcessing */ + } + useForeignDTD = XML_FALSE; + } +#endif /* XML_DTD */ + if (endDoctypeDeclHandler) { + endDoctypeDeclHandler(handlerArg); + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_INSTANCE_START: +#ifdef XML_DTD + /* if there is no DOCTYPE declaration then now is the + last chance to read the foreign DTD + */ + if (useForeignDTD) { + dtd->hasParamEntityRefs = XML_TRUE; + if (paramEntityParsing && externalEntityRefHandler) { + ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities, + externalSubsetName, + sizeof(ENTITY)); + if (!entity) + return XML_ERROR_NO_MEMORY; + entity->base = curBase; + dtd->paramEntityRead = XML_FALSE; + if (!externalEntityRefHandler(externalEntityRefHandlerArg, + 0, + entity->base, + entity->systemId, + entity->publicId)) + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + if (dtd->paramEntityRead && + !dtd->standalone && + notStandaloneHandler && + !notStandaloneHandler(handlerArg)) + return XML_ERROR_NOT_STANDALONE; + /* end of DTD - no need to update dtd->keepProcessing */ + } + } +#endif /* XML_DTD */ + processor = contentProcessor; + return contentProcessor(parser, s, end, nextPtr); + case XML_ROLE_ATTLIST_ELEMENT_NAME: + declElementType = getElementType(parser, enc, s, next); + if (!declElementType) + return XML_ERROR_NO_MEMORY; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_NAME: + declAttributeId = getAttributeId(parser, enc, s, next); + if (!declAttributeId) + return XML_ERROR_NO_MEMORY; + declAttributeIsCdata = XML_FALSE; + declAttributeType = NULL; + declAttributeIsId = XML_FALSE; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_CDATA: + declAttributeIsCdata = XML_TRUE; + declAttributeType = atypeCDATA; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_ID: + declAttributeIsId = XML_TRUE; + declAttributeType = atypeID; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_IDREF: + declAttributeType = atypeIDREF; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: + declAttributeType = atypeIDREFS; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: + declAttributeType = atypeENTITY; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: + declAttributeType = atypeENTITIES; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: + declAttributeType = atypeNMTOKEN; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: + declAttributeType = atypeNMTOKENS; + checkAttListDeclHandler: + if (dtd->keepProcessing && attlistDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_ATTRIBUTE_ENUM_VALUE: + case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: + if (dtd->keepProcessing && attlistDeclHandler) { + const XML_Char *prefix; + if (declAttributeType) { + prefix = enumValueSep; + } + else { + prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE + ? notationPrefix + : enumValueStart); + } + if (!poolAppendString(&tempPool, prefix)) + return XML_ERROR_NO_MEMORY; + if (!poolAppend(&tempPool, enc, s, next)) + return XML_ERROR_NO_MEMORY; + declAttributeType = tempPool.start; + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: + case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: + if (dtd->keepProcessing) { + if (!defineAttribute(declElementType, declAttributeId, + declAttributeIsCdata, declAttributeIsId, 0, + parser)) + return XML_ERROR_NO_MEMORY; + if (attlistDeclHandler && declAttributeType) { + if (*declAttributeType == XML_T('(') + || (*declAttributeType == XML_T('N') + && declAttributeType[1] == XML_T('O'))) { + /* Enumerated or Notation type */ + if (!poolAppendChar(&tempPool, XML_T(')')) + || !poolAppendChar(&tempPool, XML_T('\0'))) + return XML_ERROR_NO_MEMORY; + declAttributeType = tempPool.start; + poolFinish(&tempPool); + } + *eventEndPP = s; + attlistDeclHandler(handlerArg, declElementType->name, + declAttributeId->name, declAttributeType, + 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); + poolClear(&tempPool); + handleDefault = XML_FALSE; + } + } + break; + case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: + case XML_ROLE_FIXED_ATTRIBUTE_VALUE: + if (dtd->keepProcessing) { + const XML_Char *attVal; + enum XML_Error result + = storeAttributeValue(parser, enc, declAttributeIsCdata, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar, + &dtd->pool); + if (result) + return result; + attVal = poolStart(&dtd->pool); + poolFinish(&dtd->pool); + /* ID attributes aren't allowed to have a default */ + if (!defineAttribute(declElementType, declAttributeId, + declAttributeIsCdata, XML_FALSE, attVal, parser)) + return XML_ERROR_NO_MEMORY; + if (attlistDeclHandler && declAttributeType) { + if (*declAttributeType == XML_T('(') + || (*declAttributeType == XML_T('N') + && declAttributeType[1] == XML_T('O'))) { + /* Enumerated or Notation type */ + if (!poolAppendChar(&tempPool, XML_T(')')) + || !poolAppendChar(&tempPool, XML_T('\0'))) + return XML_ERROR_NO_MEMORY; + declAttributeType = tempPool.start; + poolFinish(&tempPool); + } + *eventEndPP = s; + attlistDeclHandler(handlerArg, declElementType->name, + declAttributeId->name, declAttributeType, + attVal, + role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); + poolClear(&tempPool); + handleDefault = XML_FALSE; + } + } + break; + case XML_ROLE_ENTITY_VALUE: + if (dtd->keepProcessing) { + enum XML_Error result = storeEntityValue(parser, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (declEntity) { + declEntity->textPtr = poolStart(&dtd->entityValuePool); + declEntity->textLen = poolLength(&dtd->entityValuePool); + poolFinish(&dtd->entityValuePool); + if (entityDeclHandler) { + *eventEndPP = s; + entityDeclHandler(handlerArg, + declEntity->name, + declEntity->is_param, + declEntity->textPtr, + declEntity->textLen, + curBase, 0, 0, 0); + handleDefault = XML_FALSE; + } + } + else + poolDiscard(&dtd->entityValuePool); + if (result != XML_ERROR_NONE) + return result; + } + break; + case XML_ROLE_DOCTYPE_SYSTEM_ID: +#ifdef XML_DTD + useForeignDTD = XML_FALSE; +#endif /* XML_DTD */ + dtd->hasParamEntityRefs = XML_TRUE; + if (startDoctypeDeclHandler) { + doctypeSysid = poolStoreString(&tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (doctypeSysid == NULL) + return XML_ERROR_NO_MEMORY; + poolFinish(&tempPool); + handleDefault = XML_FALSE; + } +#ifdef XML_DTD + else + /* use externalSubsetName to make doctypeSysid non-NULL + for the case where no startDoctypeDeclHandler is set */ + doctypeSysid = externalSubsetName; +#endif /* XML_DTD */ + if (!dtd->standalone +#ifdef XML_DTD + && !paramEntityParsing +#endif /* XML_DTD */ + && notStandaloneHandler + && !notStandaloneHandler(handlerArg)) + return XML_ERROR_NOT_STANDALONE; +#ifndef XML_DTD + break; +#else /* XML_DTD */ + if (!declEntity) { + declEntity = (ENTITY *)lookup(&dtd->paramEntities, + externalSubsetName, + sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; + declEntity->publicId = NULL; + } + /* fall through */ +#endif /* XML_DTD */ + case XML_ROLE_ENTITY_SYSTEM_ID: + if (dtd->keepProcessing && declEntity) { + declEntity->systemId = poolStoreString(&dtd->pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!declEntity->systemId) + return XML_ERROR_NO_MEMORY; + declEntity->base = curBase; + poolFinish(&dtd->pool); + if (entityDeclHandler) + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_ENTITY_COMPLETE: + if (dtd->keepProcessing && declEntity && entityDeclHandler) { + *eventEndPP = s; + entityDeclHandler(handlerArg, + declEntity->name, + declEntity->is_param, + 0,0, + declEntity->base, + declEntity->systemId, + declEntity->publicId, + 0); + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_ENTITY_NOTATION_NAME: + if (dtd->keepProcessing && declEntity) { + declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); + if (!declEntity->notation) + return XML_ERROR_NO_MEMORY; + poolFinish(&dtd->pool); + if (unparsedEntityDeclHandler) { + *eventEndPP = s; + unparsedEntityDeclHandler(handlerArg, + declEntity->name, + declEntity->base, + declEntity->systemId, + declEntity->publicId, + declEntity->notation); + handleDefault = XML_FALSE; + } + else if (entityDeclHandler) { + *eventEndPP = s; + entityDeclHandler(handlerArg, + declEntity->name, + 0,0,0, + declEntity->base, + declEntity->systemId, + declEntity->publicId, + declEntity->notation); + handleDefault = XML_FALSE; + } + } + break; + case XML_ROLE_GENERAL_ENTITY_NAME: + { + if (XmlPredefinedEntityName(enc, s, next)) { + declEntity = NULL; + break; + } + if (dtd->keepProcessing) { + const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); + if (!name) + return XML_ERROR_NO_MEMORY; + declEntity = (ENTITY *)lookup(&dtd->generalEntities, name, + sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; + if (declEntity->name != name) { + poolDiscard(&dtd->pool); + declEntity = NULL; + } + else { + poolFinish(&dtd->pool); + declEntity->publicId = NULL; + declEntity->is_param = XML_FALSE; + /* if we have a parent parser or are reading an internal parameter + entity, then the entity declaration is not considered "internal" + */ + declEntity->is_internal = !(parentParser || openInternalEntities); + if (entityDeclHandler) + handleDefault = XML_FALSE; + } + } + else { + poolDiscard(&dtd->pool); + declEntity = NULL; + } + } + break; + case XML_ROLE_PARAM_ENTITY_NAME: +#ifdef XML_DTD + if (dtd->keepProcessing) { + const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); + if (!name) + return XML_ERROR_NO_MEMORY; + declEntity = (ENTITY *)lookup(&dtd->paramEntities, + name, sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; + if (declEntity->name != name) { + poolDiscard(&dtd->pool); + declEntity = NULL; + } + else { + poolFinish(&dtd->pool); + declEntity->publicId = NULL; + declEntity->is_param = XML_TRUE; + /* if we have a parent parser or are reading an internal parameter + entity, then the entity declaration is not considered "internal" + */ + declEntity->is_internal = !(parentParser || openInternalEntities); + if (entityDeclHandler) + handleDefault = XML_FALSE; + } + } + else { + poolDiscard(&dtd->pool); + declEntity = NULL; + } +#else /* not XML_DTD */ + declEntity = NULL; +#endif /* XML_DTD */ + break; + case XML_ROLE_NOTATION_NAME: + declNotationPublicId = NULL; + declNotationName = NULL; + if (notationDeclHandler) { + declNotationName = poolStoreString(&tempPool, enc, s, next); + if (!declNotationName) + return XML_ERROR_NO_MEMORY; + poolFinish(&tempPool); + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_NOTATION_PUBLIC_ID: + if (!XmlIsPublicId(enc, s, next, eventPP)) + return XML_ERROR_SYNTAX; + if (declNotationName) { /* means notationDeclHandler != NULL */ + XML_Char *tem = poolStoreString(&tempPool, + enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!tem) + return XML_ERROR_NO_MEMORY; + normalizePublicId(tem); + declNotationPublicId = tem; + poolFinish(&tempPool); + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_NOTATION_SYSTEM_ID: + if (declNotationName && notationDeclHandler) { + const XML_Char *systemId + = poolStoreString(&tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!systemId) + return XML_ERROR_NO_MEMORY; + *eventEndPP = s; + notationDeclHandler(handlerArg, + declNotationName, + curBase, + systemId, + declNotationPublicId); + handleDefault = XML_FALSE; + } + poolClear(&tempPool); + break; + case XML_ROLE_NOTATION_NO_SYSTEM_ID: + if (declNotationPublicId && notationDeclHandler) { + *eventEndPP = s; + notationDeclHandler(handlerArg, + declNotationName, + curBase, + 0, + declNotationPublicId); + handleDefault = XML_FALSE; + } + poolClear(&tempPool); + break; + case XML_ROLE_ERROR: + switch (tok) { + case XML_TOK_PARAM_ENTITY_REF: + return XML_ERROR_PARAM_ENTITY_REF; + case XML_TOK_XML_DECL: + return XML_ERROR_MISPLACED_XML_PI; + default: + return XML_ERROR_SYNTAX; + } +#ifdef XML_DTD + case XML_ROLE_IGNORE_SECT: + { + enum XML_Error result; + if (defaultHandler) + reportDefault(parser, enc, s, next); + handleDefault = XML_FALSE; + result = doIgnoreSection(parser, enc, &next, end, nextPtr); + if (!next) { + processor = ignoreSectionProcessor; + return result; + } + } + break; +#endif /* XML_DTD */ + case XML_ROLE_GROUP_OPEN: + if (prologState.level >= groupSize) { + if (groupSize) { + char *temp = (char *)REALLOC(groupConnector, groupSize *= 2); + if (temp == NULL) + return XML_ERROR_NO_MEMORY; + groupConnector = temp; + if (dtd->scaffIndex) { + int *temp = (int *)REALLOC(dtd->scaffIndex, + groupSize * sizeof(int)); + if (temp == NULL) + return XML_ERROR_NO_MEMORY; + dtd->scaffIndex = temp; + } + } + else { + groupConnector = (char *)MALLOC(groupSize = 32); + if (!groupConnector) + return XML_ERROR_NO_MEMORY; + } + } + groupConnector[prologState.level] = 0; + if (dtd->in_eldecl) { + int myindex = nextScaffoldPart(parser); + if (myindex < 0) + return XML_ERROR_NO_MEMORY; + dtd->scaffIndex[dtd->scaffLevel] = myindex; + dtd->scaffLevel++; + dtd->scaffold[myindex].type = XML_CTYPE_SEQ; + if (elementDeclHandler) + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_GROUP_SEQUENCE: + if (groupConnector[prologState.level] == '|') + return XML_ERROR_SYNTAX; + groupConnector[prologState.level] = ','; + if (dtd->in_eldecl && elementDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_GROUP_CHOICE: + if (groupConnector[prologState.level] == ',') + return XML_ERROR_SYNTAX; + if (dtd->in_eldecl + && !groupConnector[prologState.level] + && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type + != XML_CTYPE_MIXED) + ) { + dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type + = XML_CTYPE_CHOICE; + if (elementDeclHandler) + handleDefault = XML_FALSE; + } + groupConnector[prologState.level] = '|'; + break; + case XML_ROLE_PARAM_ENTITY_REF: +#ifdef XML_DTD + case XML_ROLE_INNER_PARAM_ENTITY_REF: + /* PE references in internal subset are + not allowed within declarations */ + if (prologState.documentEntity && + role == XML_ROLE_INNER_PARAM_ENTITY_REF) + return XML_ERROR_PARAM_ENTITY_REF; + dtd->hasParamEntityRefs = XML_TRUE; + if (!paramEntityParsing) + dtd->keepProcessing = dtd->standalone; + else { + const XML_Char *name; + ENTITY *entity; + name = poolStoreString(&dtd->pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0); + poolDiscard(&dtd->pool); + /* first, determine if a check for an existing declaration is needed; + if yes, check that the entity exists, and that it is internal, + otherwise call the skipped entity handler + */ + if (prologState.documentEntity && + (dtd->standalone + ? !openInternalEntities + : !dtd->hasParamEntityRefs)) { + if (!entity) + return XML_ERROR_UNDEFINED_ENTITY; + else if (!entity->is_internal) + return XML_ERROR_ENTITY_DECLARED_IN_PE; + } + else if (!entity) { + dtd->keepProcessing = dtd->standalone; + /* cannot report skipped entities in declarations */ + if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) { + skippedEntityHandler(handlerArg, name, 1); + handleDefault = XML_FALSE; + } + break; + } + if (entity->open) + return XML_ERROR_RECURSIVE_ENTITY_REF; + if (entity->textPtr) { + enum XML_Error result; + result = processInternalParamEntity(parser, entity); + if (result != XML_ERROR_NONE) + return result; + handleDefault = XML_FALSE; + break; + } + if (externalEntityRefHandler) { + dtd->paramEntityRead = XML_FALSE; + entity->open = XML_TRUE; + if (!externalEntityRefHandler(externalEntityRefHandlerArg, + 0, + entity->base, + entity->systemId, + entity->publicId)) { + entity->open = XML_FALSE; + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + } + entity->open = XML_FALSE; + handleDefault = XML_FALSE; + if (!dtd->paramEntityRead) { + dtd->keepProcessing = dtd->standalone; + break; + } + } + else { + dtd->keepProcessing = dtd->standalone; + break; + } + } +#endif /* XML_DTD */ + if (!dtd->standalone && + notStandaloneHandler && + !notStandaloneHandler(handlerArg)) + return XML_ERROR_NOT_STANDALONE; + break; + + /* Element declaration stuff */ + + case XML_ROLE_ELEMENT_NAME: + if (elementDeclHandler) { + declElementType = getElementType(parser, enc, s, next); + if (!declElementType) + return XML_ERROR_NO_MEMORY; + dtd->scaffLevel = 0; + dtd->scaffCount = 0; + dtd->in_eldecl = XML_TRUE; + handleDefault = XML_FALSE; + } + break; + + case XML_ROLE_CONTENT_ANY: + case XML_ROLE_CONTENT_EMPTY: + if (dtd->in_eldecl) { + if (elementDeclHandler) { + XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content)); + if (!content) + return XML_ERROR_NO_MEMORY; + content->quant = XML_CQUANT_NONE; + content->name = NULL; + content->numchildren = 0; + content->children = NULL; + content->type = ((role == XML_ROLE_CONTENT_ANY) ? + XML_CTYPE_ANY : + XML_CTYPE_EMPTY); + *eventEndPP = s; + elementDeclHandler(handlerArg, declElementType->name, content); + handleDefault = XML_FALSE; + } + dtd->in_eldecl = XML_FALSE; + } + break; + + case XML_ROLE_CONTENT_PCDATA: + if (dtd->in_eldecl) { + dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type + = XML_CTYPE_MIXED; + if (elementDeclHandler) + handleDefault = XML_FALSE; + } + break; + + case XML_ROLE_CONTENT_ELEMENT: + quant = XML_CQUANT_NONE; + goto elementContent; + case XML_ROLE_CONTENT_ELEMENT_OPT: + quant = XML_CQUANT_OPT; + goto elementContent; + case XML_ROLE_CONTENT_ELEMENT_REP: + quant = XML_CQUANT_REP; + goto elementContent; + case XML_ROLE_CONTENT_ELEMENT_PLUS: + quant = XML_CQUANT_PLUS; + elementContent: + if (dtd->in_eldecl) { + ELEMENT_TYPE *el; + const XML_Char *name; + int nameLen; + const char *nxt = (quant == XML_CQUANT_NONE + ? next + : next - enc->minBytesPerChar); + int myindex = nextScaffoldPart(parser); + if (myindex < 0) + return XML_ERROR_NO_MEMORY; + dtd->scaffold[myindex].type = XML_CTYPE_NAME; + dtd->scaffold[myindex].quant = quant; + el = getElementType(parser, enc, s, nxt); + if (!el) + return XML_ERROR_NO_MEMORY; + name = el->name; + dtd->scaffold[myindex].name = name; + nameLen = 0; + for (; name[nameLen++]; ); + dtd->contentStringLen += nameLen; + if (elementDeclHandler) + handleDefault = XML_FALSE; + } + break; + + case XML_ROLE_GROUP_CLOSE: + quant = XML_CQUANT_NONE; + goto closeGroup; + case XML_ROLE_GROUP_CLOSE_OPT: + quant = XML_CQUANT_OPT; + goto closeGroup; + case XML_ROLE_GROUP_CLOSE_REP: + quant = XML_CQUANT_REP; + goto closeGroup; + case XML_ROLE_GROUP_CLOSE_PLUS: + quant = XML_CQUANT_PLUS; + closeGroup: + if (dtd->in_eldecl) { + if (elementDeclHandler) + handleDefault = XML_FALSE; + dtd->scaffLevel--; + dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; + if (dtd->scaffLevel == 0) { + if (!handleDefault) { + XML_Content *model = build_model(parser); + if (!model) + return XML_ERROR_NO_MEMORY; + *eventEndPP = s; + elementDeclHandler(handlerArg, declElementType->name, model); + } + dtd->in_eldecl = XML_FALSE; + dtd->contentStringLen = 0; + } + } + break; + /* End element declaration stuff */ + + case XML_ROLE_PI: + if (!reportProcessingInstruction(parser, enc, s, next)) + return XML_ERROR_NO_MEMORY; + handleDefault = XML_FALSE; + break; + case XML_ROLE_COMMENT: + if (!reportComment(parser, enc, s, next)) + return XML_ERROR_NO_MEMORY; + handleDefault = XML_FALSE; + break; + case XML_ROLE_NONE: + switch (tok) { + case XML_TOK_BOM: + handleDefault = XML_FALSE; + break; + } + break; + case XML_ROLE_DOCTYPE_NONE: + if (startDoctypeDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_ENTITY_NONE: + if (dtd->keepProcessing && entityDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_NOTATION_NONE: + if (notationDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_ATTLIST_NONE: + if (dtd->keepProcessing && attlistDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_ELEMENT_NONE: + if (elementDeclHandler) + handleDefault = XML_FALSE; + break; + } /* end of big switch */ + + if (handleDefault && defaultHandler) + reportDefault(parser, enc, s, next); + + s = next; + tok = XmlPrologTok(enc, s, end, &next); + } + /* not reached */ +} + +static enum XML_Error PTRCALL +epilogProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + processor = epilogProcessor; + eventPtr = s; + for (;;) { + const char *next = NULL; + int tok = XmlPrologTok(encoding, s, end, &next); + eventEndPtr = next; + switch (tok) { + /* report partial linebreak - it might be the last token */ + case -XML_TOK_PROLOG_S: + if (defaultHandler) { + eventEndPtr = next; + reportDefault(parser, encoding, s, next); + } + if (nextPtr) + *nextPtr = next; + return XML_ERROR_NONE; + case XML_TOK_NONE: + if (nextPtr) + *nextPtr = s; + return XML_ERROR_NONE; + case XML_TOK_PROLOG_S: + if (defaultHandler) + reportDefault(parser, encoding, s, next); + break; + case XML_TOK_PI: + if (!reportProcessingInstruction(parser, encoding, s, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_COMMENT: + if (!reportComment(parser, encoding, s, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_INVALID: + eventPtr = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + default: + return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; + } + eventPtr = s = next; + } +} + +#ifdef XML_DTD + +static enum XML_Error +processInternalParamEntity(XML_Parser parser, ENTITY *entity) +{ + const char *s, *end, *next; + int tok; + enum XML_Error result; + OPEN_INTERNAL_ENTITY openEntity; + entity->open = XML_TRUE; + openEntity.next = openInternalEntities; + openInternalEntities = &openEntity; + openEntity.entity = entity; + openEntity.internalEventPtr = NULL; + openEntity.internalEventEndPtr = NULL; + s = (char *)entity->textPtr; + end = (char *)(entity->textPtr + entity->textLen); + tok = XmlPrologTok(internalEncoding, s, end, &next); + result = doProlog(parser, internalEncoding, s, end, tok, next, 0); + entity->open = XML_FALSE; + openInternalEntities = openEntity.next; + return result; +} + +#endif /* XML_DTD */ + +static enum XML_Error PTRCALL +errorProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + return errorCode; +} + +static enum XML_Error +storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, + const char *ptr, const char *end, + STRING_POOL *pool) +{ + enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, + end, pool); + if (result) + return result; + if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) + poolChop(pool); + if (!poolAppendChar(pool, XML_T('\0'))) + return XML_ERROR_NO_MEMORY; + return XML_ERROR_NONE; +} + +static enum XML_Error +appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, + const char *ptr, const char *end, + STRING_POOL *pool) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + for (;;) { + const char *next; + int tok = XmlAttributeValueTok(enc, ptr, end, &next); + switch (tok) { + case XML_TOK_NONE: + return XML_ERROR_NONE; + case XML_TOK_INVALID: + if (enc == encoding) + eventPtr = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_CHAR_REF: + { + XML_Char buf[XML_ENCODE_MAX]; + int i; + int n = XmlCharRefNumber(enc, ptr); + if (n < 0) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_BAD_CHAR_REF; + } + if (!isCdata + && n == 0x20 /* space */ + && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) + break; + n = XmlEncode(n, (ICHAR *)buf); + if (!n) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_BAD_CHAR_REF; + } + for (i = 0; i < n; i++) { + if (!poolAppendChar(pool, buf[i])) + return XML_ERROR_NO_MEMORY; + } + } + break; + case XML_TOK_DATA_CHARS: + if (!poolAppend(pool, enc, ptr, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_TRAILING_CR: + next = ptr + enc->minBytesPerChar; + /* fall through */ + case XML_TOK_ATTRIBUTE_VALUE_S: + case XML_TOK_DATA_NEWLINE: + if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) + break; + if (!poolAppendChar(pool, 0x20)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_ENTITY_REF: + { + const XML_Char *name; + ENTITY *entity; + char checkEntityDecl; + XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, + ptr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (ch) { + if (!poolAppendChar(pool, ch)) + return XML_ERROR_NO_MEMORY; + break; + } + name = poolStoreString(&temp2Pool, enc, + ptr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0); + poolDiscard(&temp2Pool); + /* first, determine if a check for an existing declaration is needed; + if yes, check that the entity exists, and that it is internal, + otherwise call the default handler (if called from content) + */ + if (pool == &dtd->pool) /* are we called from prolog? */ + checkEntityDecl = +#ifdef XML_DTD + prologState.documentEntity && +#endif /* XML_DTD */ + (dtd->standalone + ? !openInternalEntities + : !dtd->hasParamEntityRefs); + else /* if (pool == &tempPool): we are called from content */ + checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone; + if (checkEntityDecl) { + if (!entity) + return XML_ERROR_UNDEFINED_ENTITY; + else if (!entity->is_internal) + return XML_ERROR_ENTITY_DECLARED_IN_PE; + } + else if (!entity) { + /* cannot report skipped entity here - see comments on + skippedEntityHandler + if (skippedEntityHandler) + skippedEntityHandler(handlerArg, name, 0); + */ + if ((pool == &tempPool) && defaultHandler) + reportDefault(parser, enc, ptr, next); + break; + } + if (entity->open) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_RECURSIVE_ENTITY_REF; + } + if (entity->notation) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_BINARY_ENTITY_REF; + } + if (!entity->textPtr) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; + } + else { + enum XML_Error result; + const XML_Char *textEnd = entity->textPtr + entity->textLen; + entity->open = XML_TRUE; + result = appendAttributeValue(parser, internalEncoding, isCdata, + (char *)entity->textPtr, + (char *)textEnd, pool); + entity->open = XML_FALSE; + if (result) + return result; + } + } + break; + default: + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_UNEXPECTED_STATE; + } + ptr = next; + } + /* not reached */ +} + +static enum XML_Error +storeEntityValue(XML_Parser parser, + const ENCODING *enc, + const char *entityTextPtr, + const char *entityTextEnd) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + STRING_POOL *pool = &(dtd->entityValuePool); + enum XML_Error result = XML_ERROR_NONE; +#ifdef XML_DTD + int oldInEntityValue = prologState.inEntityValue; + prologState.inEntityValue = 1; +#endif /* XML_DTD */ + /* never return Null for the value argument in EntityDeclHandler, + since this would indicate an external entity; therefore we + have to make sure that entityValuePool.start is not null */ + if (!pool->blocks) { + if (!poolGrow(pool)) + return XML_ERROR_NO_MEMORY; + } + + for (;;) { + const char *next; + int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); + switch (tok) { + case XML_TOK_PARAM_ENTITY_REF: +#ifdef XML_DTD + if (isParamEntity || enc != encoding) { + const XML_Char *name; + ENTITY *entity; + name = poolStoreString(&tempPool, enc, + entityTextPtr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) { + result = XML_ERROR_NO_MEMORY; + goto endEntityValue; + } + entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0); + poolDiscard(&tempPool); + if (!entity) { + /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ + /* cannot report skipped entity here - see comments on + skippedEntityHandler + if (skippedEntityHandler) + skippedEntityHandler(handlerArg, name, 0); + */ + dtd->keepProcessing = dtd->standalone; + goto endEntityValue; + } + if (entity->open) { + if (enc == encoding) + eventPtr = entityTextPtr; + result = XML_ERROR_RECURSIVE_ENTITY_REF; + goto endEntityValue; + } + if (entity->systemId) { + if (externalEntityRefHandler) { + dtd->paramEntityRead = XML_FALSE; + entity->open = XML_TRUE; + if (!externalEntityRefHandler(externalEntityRefHandlerArg, + 0, + entity->base, + entity->systemId, + entity->publicId)) { + entity->open = XML_FALSE; + result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; + goto endEntityValue; + } + entity->open = XML_FALSE; + if (!dtd->paramEntityRead) + dtd->keepProcessing = dtd->standalone; + } + else + dtd->keepProcessing = dtd->standalone; + } + else { + entity->open = XML_TRUE; + result = storeEntityValue(parser, + internalEncoding, + (char *)entity->textPtr, + (char *)(entity->textPtr + + entity->textLen)); + entity->open = XML_FALSE; + if (result) + goto endEntityValue; + } + break; + } +#endif /* XML_DTD */ + /* in the internal subset, PE references are not legal + within markup declarations, e.g entity values in this case */ + eventPtr = entityTextPtr; + result = XML_ERROR_PARAM_ENTITY_REF; + goto endEntityValue; + case XML_TOK_NONE: + result = XML_ERROR_NONE; + goto endEntityValue; + case XML_TOK_ENTITY_REF: + case XML_TOK_DATA_CHARS: + if (!poolAppend(pool, enc, entityTextPtr, next)) { + result = XML_ERROR_NO_MEMORY; + goto endEntityValue; + } + break; + case XML_TOK_TRAILING_CR: + next = entityTextPtr + enc->minBytesPerChar; + /* fall through */ + case XML_TOK_DATA_NEWLINE: + if (pool->end == pool->ptr && !poolGrow(pool)) { + result = XML_ERROR_NO_MEMORY; + goto endEntityValue; + } + *(pool->ptr)++ = 0xA; + break; + case XML_TOK_CHAR_REF: + { + XML_Char buf[XML_ENCODE_MAX]; + int i; + int n = XmlCharRefNumber(enc, entityTextPtr); + if (n < 0) { + if (enc == encoding) + eventPtr = entityTextPtr; + result = XML_ERROR_BAD_CHAR_REF; + goto endEntityValue; + } + n = XmlEncode(n, (ICHAR *)buf); + if (!n) { + if (enc == encoding) + eventPtr = entityTextPtr; + result = XML_ERROR_BAD_CHAR_REF; + goto endEntityValue; + } + for (i = 0; i < n; i++) { + if (pool->end == pool->ptr && !poolGrow(pool)) { + result = XML_ERROR_NO_MEMORY; + goto endEntityValue; + } + *(pool->ptr)++ = buf[i]; + } + } + break; + case XML_TOK_PARTIAL: + if (enc == encoding) + eventPtr = entityTextPtr; + result = XML_ERROR_INVALID_TOKEN; + goto endEntityValue; + case XML_TOK_INVALID: + if (enc == encoding) + eventPtr = next; + result = XML_ERROR_INVALID_TOKEN; + goto endEntityValue; + default: + if (enc == encoding) + eventPtr = entityTextPtr; + result = XML_ERROR_UNEXPECTED_STATE; + goto endEntityValue; + } + entityTextPtr = next; + } +endEntityValue: +#ifdef XML_DTD + prologState.inEntityValue = oldInEntityValue; +#endif /* XML_DTD */ + return result; +} + +static void FASTCALL +normalizeLines(XML_Char *s) +{ + XML_Char *p; + for (;; s++) { + if (*s == XML_T('\0')) + return; + if (*s == 0xD) + break; + } + p = s; + do { + if (*s == 0xD) { + *p++ = 0xA; + if (*++s == 0xA) + s++; + } + else + *p++ = *s++; + } while (*s); + *p = XML_T('\0'); +} + +static int +reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end) +{ + const XML_Char *target; + XML_Char *data; + const char *tem; + if (!processingInstructionHandler) { + if (defaultHandler) + reportDefault(parser, enc, start, end); + return 1; + } + start += enc->minBytesPerChar * 2; + tem = start + XmlNameLength(enc, start); + target = poolStoreString(&tempPool, enc, start, tem); + if (!target) + return 0; + poolFinish(&tempPool); + data = poolStoreString(&tempPool, enc, + XmlSkipS(enc, tem), + end - enc->minBytesPerChar*2); + if (!data) + return 0; + normalizeLines(data); + processingInstructionHandler(handlerArg, target, data); + poolClear(&tempPool); + return 1; +} + +static int +reportComment(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end) +{ + XML_Char *data; + if (!commentHandler) { + if (defaultHandler) + reportDefault(parser, enc, start, end); + return 1; + } + data = poolStoreString(&tempPool, + enc, + start + enc->minBytesPerChar * 4, + end - enc->minBytesPerChar * 3); + if (!data) + return 0; + normalizeLines(data); + commentHandler(handlerArg, data); + poolClear(&tempPool); + return 1; +} + +static void +reportDefault(XML_Parser parser, const ENCODING *enc, + const char *s, const char *end) +{ + if (MUST_CONVERT(enc, s)) { + const char **eventPP; + const char **eventEndPP; + if (enc == encoding) { + eventPP = &eventPtr; + eventEndPP = &eventEndPtr; + } + else { + eventPP = &(openInternalEntities->internalEventPtr); + eventEndPP = &(openInternalEntities->internalEventEndPtr); + } + do { + ICHAR *dataPtr = (ICHAR *)dataBuf; + XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); + *eventEndPP = s; + defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); + *eventPP = s; + } while (s != end); + } + else + defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s); +} + + +static int +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, + XML_Bool isId, const XML_Char *value, XML_Parser parser) +{ + DEFAULT_ATTRIBUTE *att; + if (value || isId) { + /* The handling of default attributes gets messed up if we have + a default which duplicates a non-default. */ + int i; + for (i = 0; i < type->nDefaultAtts; i++) + if (attId == type->defaultAtts[i].id) + return 1; + if (isId && !type->idAtt && !attId->xmlns) + type->idAtt = attId; + } + if (type->nDefaultAtts == type->allocDefaultAtts) { + if (type->allocDefaultAtts == 0) { + type->allocDefaultAtts = 8; + type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts + * sizeof(DEFAULT_ATTRIBUTE)); + if (!type->defaultAtts) + return 0; + } + else { + DEFAULT_ATTRIBUTE *temp; + int count = type->allocDefaultAtts * 2; + temp = (DEFAULT_ATTRIBUTE *) + REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); + if (temp == NULL) + return 0; + type->allocDefaultAtts = count; + type->defaultAtts = temp; + } + } + att = type->defaultAtts + type->nDefaultAtts; + att->id = attId; + att->value = value; + att->isCdata = isCdata; + if (!isCdata) + attId->maybeTokenized = XML_TRUE; + type->nDefaultAtts += 1; + return 1; +} + +static int +setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + const XML_Char *name; + for (name = elementType->name; *name; name++) { + if (*name == XML_T(':')) { + PREFIX *prefix; + const XML_Char *s; + for (s = elementType->name; s != name; s++) { + if (!poolAppendChar(&dtd->pool, *s)) + return 0; + } + if (!poolAppendChar(&dtd->pool, XML_T('\0'))) + return 0; + prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool), + sizeof(PREFIX)); + if (!prefix) + return 0; + if (prefix->name == poolStart(&dtd->pool)) + poolFinish(&dtd->pool); + else + poolDiscard(&dtd->pool); + elementType->prefix = prefix; + + } + } + return 1; +} + +static ATTRIBUTE_ID * +getAttributeId(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + ATTRIBUTE_ID *id; + const XML_Char *name; + if (!poolAppendChar(&dtd->pool, XML_T('\0'))) + return NULL; + name = poolStoreString(&dtd->pool, enc, start, end); + if (!name) + return NULL; + ++name; + id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID)); + if (!id) + return NULL; + if (id->name != name) + poolDiscard(&dtd->pool); + else { + poolFinish(&dtd->pool); + if (!ns) + ; + else if (name[0] == XML_T('x') + && name[1] == XML_T('m') + && name[2] == XML_T('l') + && name[3] == XML_T('n') + && name[4] == XML_T('s') + && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) { + if (name[5] == XML_T('\0')) + id->prefix = &dtd->defaultPrefix; + else + id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX)); + id->xmlns = XML_TRUE; + } + else { + int i; + for (i = 0; name[i]; i++) { + if (name[i] == XML_T(':')) { + int j; + for (j = 0; j < i; j++) { + if (!poolAppendChar(&dtd->pool, name[j])) + return NULL; + } + if (!poolAppendChar(&dtd->pool, XML_T('\0'))) + return NULL; + id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool), + sizeof(PREFIX)); + if (id->prefix->name == poolStart(&dtd->pool)) + poolFinish(&dtd->pool); + else + poolDiscard(&dtd->pool); + break; + } + } + } + } + return id; +} + +#define CONTEXT_SEP XML_T('\f') + +static const XML_Char * +getContext(XML_Parser parser) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + HASH_TABLE_ITER iter; + XML_Bool needSep = XML_FALSE; + + if (dtd->defaultPrefix.binding) { + int i; + int len; + if (!poolAppendChar(&tempPool, XML_T('='))) + return NULL; + len = dtd->defaultPrefix.binding->uriLen; + if (namespaceSeparator != XML_T('\0')) + len--; + for (i = 0; i < len; i++) + if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i])) + return NULL; + needSep = XML_TRUE; + } + + hashTableIterInit(&iter, &(dtd->prefixes)); + for (;;) { + int i; + int len; + const XML_Char *s; + PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); + if (!prefix) + break; + if (!prefix->binding) + continue; + if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) + return NULL; + for (s = prefix->name; *s; s++) + if (!poolAppendChar(&tempPool, *s)) + return NULL; + if (!poolAppendChar(&tempPool, XML_T('='))) + return NULL; + len = prefix->binding->uriLen; + if (namespaceSeparator != XML_T('\0')) + len--; + for (i = 0; i < len; i++) + if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) + return NULL; + needSep = XML_TRUE; + } + + + hashTableIterInit(&iter, &(dtd->generalEntities)); + for (;;) { + const XML_Char *s; + ENTITY *e = (ENTITY *)hashTableIterNext(&iter); + if (!e) + break; + if (!e->open) + continue; + if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) + return NULL; + for (s = e->name; *s; s++) + if (!poolAppendChar(&tempPool, *s)) + return 0; + needSep = XML_TRUE; + } + + if (!poolAppendChar(&tempPool, XML_T('\0'))) + return NULL; + return tempPool.start; +} + +static XML_Bool +setContext(XML_Parser parser, const XML_Char *context) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + const XML_Char *s = context; + + while (*context != XML_T('\0')) { + if (*s == CONTEXT_SEP || *s == XML_T('\0')) { + ENTITY *e; + if (!poolAppendChar(&tempPool, XML_T('\0'))) + return XML_FALSE; + e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0); + if (e) + e->open = XML_TRUE; + if (*s != XML_T('\0')) + s++; + context = s; + poolDiscard(&tempPool); + } + else if (*s == XML_T('=')) { + PREFIX *prefix; + if (poolLength(&tempPool) == 0) + prefix = &dtd->defaultPrefix; + else { + if (!poolAppendChar(&tempPool, XML_T('\0'))) + return XML_FALSE; + prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool), + sizeof(PREFIX)); + if (!prefix) + return XML_FALSE; + if (prefix->name == poolStart(&tempPool)) { + prefix->name = poolCopyString(&dtd->pool, prefix->name); + if (!prefix->name) + return XML_FALSE; + } + poolDiscard(&tempPool); + } + for (context = s + 1; + *context != CONTEXT_SEP && *context != XML_T('\0'); + context++) + if (!poolAppendChar(&tempPool, *context)) + return XML_FALSE; + if (!poolAppendChar(&tempPool, XML_T('\0'))) + return XML_FALSE; + if (addBinding(parser, prefix, 0, poolStart(&tempPool), + &inheritedBindings) != XML_ERROR_NONE) + return XML_FALSE; + poolDiscard(&tempPool); + if (*context != XML_T('\0')) + ++context; + s = context; + } + else { + if (!poolAppendChar(&tempPool, *s)) + return XML_FALSE; + s++; + } + } + return XML_TRUE; +} + +static void FASTCALL +normalizePublicId(XML_Char *publicId) +{ + XML_Char *p = publicId; + XML_Char *s; + for (s = publicId; *s; s++) { + switch (*s) { + case 0x20: + case 0xD: + case 0xA: + if (p != publicId && p[-1] != 0x20) + *p++ = 0x20; + break; + default: + *p++ = *s; + } + } + if (p != publicId && p[-1] == 0x20) + --p; + *p = XML_T('\0'); +} + +static DTD * +dtdCreate(const XML_Memory_Handling_Suite *ms) +{ + DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD)); + if (p == NULL) + return p; + poolInit(&(p->pool), ms); +#ifdef XML_DTD + poolInit(&(p->entityValuePool), ms); +#endif /* XML_DTD */ + hashTableInit(&(p->generalEntities), ms); + hashTableInit(&(p->elementTypes), ms); + hashTableInit(&(p->attributeIds), ms); + hashTableInit(&(p->prefixes), ms); +#ifdef XML_DTD + p->paramEntityRead = XML_FALSE; + hashTableInit(&(p->paramEntities), ms); +#endif /* XML_DTD */ + p->defaultPrefix.name = NULL; + p->defaultPrefix.binding = NULL; + + p->in_eldecl = XML_FALSE; + p->scaffIndex = NULL; + p->scaffold = NULL; + p->scaffLevel = 0; + p->scaffSize = 0; + p->scaffCount = 0; + p->contentStringLen = 0; + + p->keepProcessing = XML_TRUE; + p->hasParamEntityRefs = XML_FALSE; + p->standalone = XML_FALSE; + return p; +} + +static void +dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) +{ + HASH_TABLE_ITER iter; + hashTableIterInit(&iter, &(p->elementTypes)); + for (;;) { + ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); + if (!e) + break; + if (e->allocDefaultAtts != 0) + ms->free_fcn(e->defaultAtts); + } + hashTableClear(&(p->generalEntities)); +#ifdef XML_DTD + p->paramEntityRead = XML_FALSE; + hashTableClear(&(p->paramEntities)); +#endif /* XML_DTD */ + hashTableClear(&(p->elementTypes)); + hashTableClear(&(p->attributeIds)); + hashTableClear(&(p->prefixes)); + poolClear(&(p->pool)); +#ifdef XML_DTD + poolClear(&(p->entityValuePool)); +#endif /* XML_DTD */ + p->defaultPrefix.name = NULL; + p->defaultPrefix.binding = NULL; + + p->in_eldecl = XML_FALSE; + if (p->scaffIndex) { + ms->free_fcn(p->scaffIndex); + p->scaffIndex = NULL; + } + if (p->scaffold) { + ms->free_fcn(p->scaffold); + p->scaffold = NULL; + } + p->scaffLevel = 0; + p->scaffSize = 0; + p->scaffCount = 0; + p->contentStringLen = 0; + + p->keepProcessing = XML_TRUE; + p->hasParamEntityRefs = XML_FALSE; + p->standalone = XML_FALSE; +} + +static void +dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) +{ + HASH_TABLE_ITER iter; + hashTableIterInit(&iter, &(p->elementTypes)); + for (;;) { + ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); + if (!e) + break; + if (e->allocDefaultAtts != 0) + ms->free_fcn(e->defaultAtts); + } + hashTableDestroy(&(p->generalEntities)); +#ifdef XML_DTD + hashTableDestroy(&(p->paramEntities)); +#endif /* XML_DTD */ + hashTableDestroy(&(p->elementTypes)); + hashTableDestroy(&(p->attributeIds)); + hashTableDestroy(&(p->prefixes)); + poolDestroy(&(p->pool)); +#ifdef XML_DTD + poolDestroy(&(p->entityValuePool)); +#endif /* XML_DTD */ + if (isDocEntity) { + if (p->scaffIndex) + ms->free_fcn(p->scaffIndex); + if (p->scaffold) + ms->free_fcn(p->scaffold); + } + ms->free_fcn(p); +} + +/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. + The new DTD has already been initialized. +*/ +static int +dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms) +{ + HASH_TABLE_ITER iter; + + /* Copy the prefix table. */ + + hashTableIterInit(&iter, &(oldDtd->prefixes)); + for (;;) { + const XML_Char *name; + const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); + if (!oldP) + break; + name = poolCopyString(&(newDtd->pool), oldP->name); + if (!name) + return 0; + if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX))) + return 0; + } + + hashTableIterInit(&iter, &(oldDtd->attributeIds)); + + /* Copy the attribute id table. */ + + for (;;) { + ATTRIBUTE_ID *newA; + const XML_Char *name; + const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); + + if (!oldA) + break; + /* Remember to allocate the scratch byte before the name. */ + if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) + return 0; + name = poolCopyString(&(newDtd->pool), oldA->name); + if (!name) + return 0; + ++name; + newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, + sizeof(ATTRIBUTE_ID)); + if (!newA) + return 0; + newA->maybeTokenized = oldA->maybeTokenized; + if (oldA->prefix) { + newA->xmlns = oldA->xmlns; + if (oldA->prefix == &oldDtd->defaultPrefix) + newA->prefix = &newDtd->defaultPrefix; + else + newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), + oldA->prefix->name, 0); + } + } + + /* Copy the element type table. */ + + hashTableIterInit(&iter, &(oldDtd->elementTypes)); + + for (;;) { + int i; + ELEMENT_TYPE *newE; + const XML_Char *name; + const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); + if (!oldE) + break; + name = poolCopyString(&(newDtd->pool), oldE->name); + if (!name) + return 0; + newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, + sizeof(ELEMENT_TYPE)); + if (!newE) + return 0; + if (oldE->nDefaultAtts) { + newE->defaultAtts = (DEFAULT_ATTRIBUTE *) + ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); + if (!newE->defaultAtts) { + ms->free_fcn(newE); + return 0; + } + } + if (oldE->idAtt) + newE->idAtt = (ATTRIBUTE_ID *) + lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0); + newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; + if (oldE->prefix) + newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), + oldE->prefix->name, 0); + for (i = 0; i < newE->nDefaultAtts; i++) { + newE->defaultAtts[i].id = (ATTRIBUTE_ID *) + lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); + newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; + if (oldE->defaultAtts[i].value) { + newE->defaultAtts[i].value + = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); + if (!newE->defaultAtts[i].value) + return 0; + } + else + newE->defaultAtts[i].value = NULL; + } + } + + /* Copy the entity tables. */ + if (!copyEntityTable(&(newDtd->generalEntities), + &(newDtd->pool), + &(oldDtd->generalEntities))) + return 0; + +#ifdef XML_DTD + if (!copyEntityTable(&(newDtd->paramEntities), + &(newDtd->pool), + &(oldDtd->paramEntities))) + return 0; + newDtd->paramEntityRead = oldDtd->paramEntityRead; +#endif /* XML_DTD */ + + newDtd->keepProcessing = oldDtd->keepProcessing; + newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; + newDtd->standalone = oldDtd->standalone; + + /* Don't want deep copying for scaffolding */ + newDtd->in_eldecl = oldDtd->in_eldecl; + newDtd->scaffold = oldDtd->scaffold; + newDtd->contentStringLen = oldDtd->contentStringLen; + newDtd->scaffSize = oldDtd->scaffSize; + newDtd->scaffLevel = oldDtd->scaffLevel; + newDtd->scaffIndex = oldDtd->scaffIndex; + + return 1; +} /* End dtdCopy */ + +static int +copyEntityTable(HASH_TABLE *newTable, + STRING_POOL *newPool, + const HASH_TABLE *oldTable) +{ + HASH_TABLE_ITER iter; + const XML_Char *cachedOldBase = NULL; + const XML_Char *cachedNewBase = NULL; + + hashTableIterInit(&iter, oldTable); + + for (;;) { + ENTITY *newE; + const XML_Char *name; + const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); + if (!oldE) + break; + name = poolCopyString(newPool, oldE->name); + if (!name) + return 0; + newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY)); + if (!newE) + return 0; + if (oldE->systemId) { + const XML_Char *tem = poolCopyString(newPool, oldE->systemId); + if (!tem) + return 0; + newE->systemId = tem; + if (oldE->base) { + if (oldE->base == cachedOldBase) + newE->base = cachedNewBase; + else { + cachedOldBase = oldE->base; + tem = poolCopyString(newPool, cachedOldBase); + if (!tem) + return 0; + cachedNewBase = newE->base = tem; + } + } + if (oldE->publicId) { + tem = poolCopyString(newPool, oldE->publicId); + if (!tem) + return 0; + newE->publicId = tem; + } + } + else { + const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, + oldE->textLen); + if (!tem) + return 0; + newE->textPtr = tem; + newE->textLen = oldE->textLen; + } + if (oldE->notation) { + const XML_Char *tem = poolCopyString(newPool, oldE->notation); + if (!tem) + return 0; + newE->notation = tem; + } + newE->is_param = oldE->is_param; + newE->is_internal = oldE->is_internal; + } + return 1; +} + +#define INIT_SIZE 64 + +static int FASTCALL +keyeq(KEY s1, KEY s2) +{ + for (; *s1 == *s2; s1++, s2++) + if (*s1 == 0) + return 1; + return 0; +} + +static unsigned long FASTCALL +hash(KEY s) +{ + unsigned long h = 0; + while (*s) + h = (h << 5) + h + (unsigned char)*s++; + return h; +} + +static NAMED * +lookup(HASH_TABLE *table, KEY name, size_t createSize) +{ + size_t i; + if (table->size == 0) { + size_t tsize; + + if (!createSize) + return NULL; + tsize = INIT_SIZE * sizeof(NAMED *); + table->v = (NAMED **)table->mem->malloc_fcn(tsize); + if (!table->v) + return NULL; + memset(table->v, 0, tsize); + table->size = INIT_SIZE; + table->usedLim = INIT_SIZE / 2; + i = hash(name) & (table->size - 1); + } + else { + unsigned long h = hash(name); + for (i = h & (table->size - 1); + table->v[i]; + i == 0 ? i = table->size - 1 : --i) { + if (keyeq(name, table->v[i]->name)) + return table->v[i]; + } + if (!createSize) + return NULL; + if (table->used == table->usedLim) { + /* check for overflow */ + size_t newSize = table->size * 2; + size_t tsize = newSize * sizeof(NAMED *); + NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); + if (!newV) + return NULL; + memset(newV, 0, tsize); + for (i = 0; i < table->size; i++) + if (table->v[i]) { + size_t j; + for (j = hash(table->v[i]->name) & (newSize - 1); + newV[j]; + j == 0 ? j = newSize - 1 : --j) + ; + newV[j] = table->v[i]; + } + table->mem->free_fcn(table->v); + table->v = newV; + table->size = newSize; + table->usedLim = newSize/2; + for (i = h & (table->size - 1); + table->v[i]; + i == 0 ? i = table->size - 1 : --i) + ; + } + } + table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize); + if (!table->v[i]) + return NULL; + memset(table->v[i], 0, createSize); + table->v[i]->name = name; + (table->used)++; + return table->v[i]; +} + +static void FASTCALL +hashTableClear(HASH_TABLE *table) +{ + size_t i; + for (i = 0; i < table->size; i++) { + NAMED *p = table->v[i]; + if (p) { + table->mem->free_fcn(p); + table->v[i] = NULL; + } + } + table->usedLim = table->size / 2; + table->used = 0; +} + +static void FASTCALL +hashTableDestroy(HASH_TABLE *table) +{ + size_t i; + for (i = 0; i < table->size; i++) { + NAMED *p = table->v[i]; + if (p) + table->mem->free_fcn(p); + } + if (table->v) + table->mem->free_fcn(table->v); +} + +static void FASTCALL +hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) +{ + p->size = 0; + p->usedLim = 0; + p->used = 0; + p->v = NULL; + p->mem = ms; +} + +static void FASTCALL +hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) +{ + iter->p = table->v; + iter->end = iter->p + table->size; +} + +static NAMED * FASTCALL +hashTableIterNext(HASH_TABLE_ITER *iter) +{ + while (iter->p != iter->end) { + NAMED *tem = *(iter->p)++; + if (tem) + return tem; + } + return NULL; +} + +static void FASTCALL +poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) +{ + pool->blocks = NULL; + pool->freeBlocks = NULL; + pool->start = NULL; + pool->ptr = NULL; + pool->end = NULL; + pool->mem = ms; +} + +static void FASTCALL +poolClear(STRING_POOL *pool) +{ + if (!pool->freeBlocks) + pool->freeBlocks = pool->blocks; + else { + BLOCK *p = pool->blocks; + while (p) { + BLOCK *tem = p->next; + p->next = pool->freeBlocks; + pool->freeBlocks = p; + p = tem; + } + } + pool->blocks = NULL; + pool->start = NULL; + pool->ptr = NULL; + pool->end = NULL; +} + +static void FASTCALL +poolDestroy(STRING_POOL *pool) +{ + BLOCK *p = pool->blocks; + while (p) { + BLOCK *tem = p->next; + pool->mem->free_fcn(p); + p = tem; + } + p = pool->freeBlocks; + while (p) { + BLOCK *tem = p->next; + pool->mem->free_fcn(p); + p = tem; + } +} + +static XML_Char * +poolAppend(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end) +{ + if (!pool->ptr && !poolGrow(pool)) + return NULL; + for (;;) { + XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); + if (ptr == end) + break; + if (!poolGrow(pool)) + return NULL; + } + return pool->start; +} + +static const XML_Char * FASTCALL +poolCopyString(STRING_POOL *pool, const XML_Char *s) +{ + do { + if (!poolAppendChar(pool, *s)) + return NULL; + } while (*s++); + s = pool->start; + poolFinish(pool); + return s; +} + +static const XML_Char * +poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) +{ + if (!pool->ptr && !poolGrow(pool)) + return NULL; + for (; n > 0; --n, s++) { + if (!poolAppendChar(pool, *s)) + return NULL; + } + s = pool->start; + poolFinish(pool); + return s; +} + +static const XML_Char * FASTCALL +poolAppendString(STRING_POOL *pool, const XML_Char *s) +{ + while (*s) { + if (!poolAppendChar(pool, *s)) + return NULL; + s++; + } + return pool->start; +} + +static XML_Char * +poolStoreString(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end) +{ + if (!poolAppend(pool, enc, ptr, end)) + return NULL; + if (pool->ptr == pool->end && !poolGrow(pool)) + return NULL; + *(pool->ptr)++ = 0; + return pool->start; +} + +static XML_Bool FASTCALL +poolGrow(STRING_POOL *pool) +{ + if (pool->freeBlocks) { + if (pool->start == 0) { + pool->blocks = pool->freeBlocks; + pool->freeBlocks = pool->freeBlocks->next; + pool->blocks->next = NULL; + pool->start = pool->blocks->s; + pool->end = pool->start + pool->blocks->size; + pool->ptr = pool->start; + return XML_TRUE; + } + if (pool->end - pool->start < pool->freeBlocks->size) { + BLOCK *tem = pool->freeBlocks->next; + pool->freeBlocks->next = pool->blocks; + pool->blocks = pool->freeBlocks; + pool->freeBlocks = tem; + memcpy(pool->blocks->s, pool->start, + (pool->end - pool->start) * sizeof(XML_Char)); + pool->ptr = pool->blocks->s + (pool->ptr - pool->start); + pool->start = pool->blocks->s; + pool->end = pool->start + pool->blocks->size; + return XML_TRUE; + } + } + if (pool->blocks && pool->start == pool->blocks->s) { + int blockSize = (pool->end - pool->start)*2; + pool->blocks = (BLOCK *) + pool->mem->realloc_fcn(pool->blocks, + (offsetof(BLOCK, s) + + blockSize * sizeof(XML_Char))); + if (pool->blocks == NULL) + return XML_FALSE; + pool->blocks->size = blockSize; + pool->ptr = pool->blocks->s + (pool->ptr - pool->start); + pool->start = pool->blocks->s; + pool->end = pool->start + blockSize; + } + else { + BLOCK *tem; + int blockSize = pool->end - pool->start; + if (blockSize < INIT_BLOCK_SIZE) + blockSize = INIT_BLOCK_SIZE; + else + blockSize *= 2; + tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s) + + blockSize * sizeof(XML_Char)); + if (!tem) + return XML_FALSE; + tem->size = blockSize; + tem->next = pool->blocks; + pool->blocks = tem; + if (pool->ptr != pool->start) + memcpy(tem->s, pool->start, + (pool->ptr - pool->start) * sizeof(XML_Char)); + pool->ptr = tem->s + (pool->ptr - pool->start); + pool->start = tem->s; + pool->end = tem->s + blockSize; + } + return XML_TRUE; +} + +static int FASTCALL +nextScaffoldPart(XML_Parser parser) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + CONTENT_SCAFFOLD * me; + int next; + + if (!dtd->scaffIndex) { + dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int)); + if (!dtd->scaffIndex) + return -1; + dtd->scaffIndex[0] = 0; + } + + if (dtd->scaffCount >= dtd->scaffSize) { + CONTENT_SCAFFOLD *temp; + if (dtd->scaffold) { + temp = (CONTENT_SCAFFOLD *) + REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); + if (temp == NULL) + return -1; + dtd->scaffSize *= 2; + } + else { + temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS + * sizeof(CONTENT_SCAFFOLD)); + if (temp == NULL) + return -1; + dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; + } + dtd->scaffold = temp; + } + next = dtd->scaffCount++; + me = &dtd->scaffold[next]; + if (dtd->scaffLevel) { + CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]]; + if (parent->lastchild) { + dtd->scaffold[parent->lastchild].nextsib = next; + } + if (!parent->childcnt) + parent->firstchild = next; + parent->lastchild = next; + parent->childcnt++; + } + me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; + return next; +} + +static void +build_node(XML_Parser parser, + int src_node, + XML_Content *dest, + XML_Content **contpos, + XML_Char **strpos) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + dest->type = dtd->scaffold[src_node].type; + dest->quant = dtd->scaffold[src_node].quant; + if (dest->type == XML_CTYPE_NAME) { + const XML_Char *src; + dest->name = *strpos; + src = dtd->scaffold[src_node].name; + for (;;) { + *(*strpos)++ = *src; + if (!*src) + break; + src++; + } + dest->numchildren = 0; + dest->children = NULL; + } + else { + unsigned int i; + int cn; + dest->numchildren = dtd->scaffold[src_node].childcnt; + dest->children = *contpos; + *contpos += dest->numchildren; + for (i = 0, cn = dtd->scaffold[src_node].firstchild; + i < dest->numchildren; + i++, cn = dtd->scaffold[cn].nextsib) { + build_node(parser, cn, &(dest->children[i]), contpos, strpos); + } + dest->name = NULL; + } +} + +static XML_Content * +build_model (XML_Parser parser) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + XML_Content *ret; + XML_Content *cpos; + XML_Char * str; + int allocsize = (dtd->scaffCount * sizeof(XML_Content) + + (dtd->contentStringLen * sizeof(XML_Char))); + + ret = (XML_Content *)MALLOC(allocsize); + if (!ret) + return NULL; + + str = (XML_Char *) (&ret[dtd->scaffCount]); + cpos = &ret[1]; + + build_node(parser, 0, ret, &cpos, &str); + return ret; +} + +static ELEMENT_TYPE * +getElementType(XML_Parser parser, + const ENCODING *enc, + const char *ptr, + const char *end) +{ + DTD * const dtd = _dtd; /* save one level of indirection */ + const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); + ELEMENT_TYPE *ret; + + if (!name) + return NULL; + ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); + if (!ret) + return NULL; + if (ret->name != name) + poolDiscard(&dtd->pool); + else { + poolFinish(&dtd->pool); + if (!setElementTypePrefix(parser, ret)) + return NULL; + } + return ret; +} diff --git a/macosx/expat/xmlrole.c b/macosx/expat/xmlrole.c new file mode 100644 index 0000000..8ef185d --- /dev/null +++ b/macosx/expat/xmlrole.c @@ -0,0 +1,1321 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifdef COMPILED_FROM_DSP +#include "winconfig.h" +#elif defined(MACOS_CLASSIC) +#include "macconfig.h" +#else +#include +#endif /* ndef COMPILED_FROM_DSP */ + +#include "internal.h" +#include "xmlrole.h" +#include "ascii.h" + +/* Doesn't check: + + that ,| are not mixed in a model group + content of literals + +*/ + +static const char KW_ANY[] = { + ASCII_A, ASCII_N, ASCII_Y, '\0' }; +static const char KW_ATTLIST[] = { + ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' }; +static const char KW_CDATA[] = { + ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; +static const char KW_DOCTYPE[] = { + ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' }; +static const char KW_ELEMENT[] = { + ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' }; +static const char KW_EMPTY[] = { + ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' }; +static const char KW_ENTITIES[] = { + ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, + '\0' }; +static const char KW_ENTITY[] = { + ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; +static const char KW_FIXED[] = { + ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' }; +static const char KW_ID[] = { + ASCII_I, ASCII_D, '\0' }; +static const char KW_IDREF[] = { + ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; +static const char KW_IDREFS[] = { + ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; +static const char KW_IGNORE[] = { + ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' }; +static const char KW_IMPLIED[] = { + ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' }; +static const char KW_INCLUDE[] = { + ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' }; +static const char KW_NDATA[] = { + ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; +static const char KW_NMTOKEN[] = { + ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; +static const char KW_NMTOKENS[] = { + ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, + '\0' }; +static const char KW_NOTATION[] = + { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, + '\0' }; +static const char KW_PCDATA[] = { + ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; +static const char KW_PUBLIC[] = { + ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' }; +static const char KW_REQUIRED[] = { + ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, + '\0' }; +static const char KW_SYSTEM[] = { + ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' }; + +#ifndef MIN_BYTES_PER_CHAR +#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) +#endif + +#ifdef XML_DTD +#define setTopLevel(state) \ + ((state)->handler = ((state)->documentEntity \ + ? internalSubset \ + : externalSubset1)) +#else /* not XML_DTD */ +#define setTopLevel(state) ((state)->handler = internalSubset) +#endif /* not XML_DTD */ + +typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc); + +static PROLOG_HANDLER + prolog0, prolog1, prolog2, + doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, + internalSubset, + entity0, entity1, entity2, entity3, entity4, entity5, entity6, + entity7, entity8, entity9, entity10, + notation0, notation1, notation2, notation3, notation4, + attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, + attlist7, attlist8, attlist9, + element0, element1, element2, element3, element4, element5, element6, + element7, +#ifdef XML_DTD + externalSubset0, externalSubset1, + condSect0, condSect1, condSect2, +#endif /* XML_DTD */ + declClose, + error; + +static int FASTCALL common(PROLOG_STATE *state, int tok); + +static int PTRCALL +prolog0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + state->handler = prolog1; + return XML_ROLE_NONE; + case XML_TOK_XML_DECL: + state->handler = prolog1; + return XML_ROLE_XML_DECL; + case XML_TOK_PI: + state->handler = prolog1; + return XML_ROLE_PI; + case XML_TOK_COMMENT: + state->handler = prolog1; + return XML_ROLE_COMMENT; + case XML_TOK_BOM: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (!XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_DOCTYPE)) + break; + state->handler = doctype0; + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static int PTRCALL +prolog1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PI: + return XML_ROLE_PI; + case XML_TOK_COMMENT: + return XML_ROLE_COMMENT; + case XML_TOK_BOM: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (!XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_DOCTYPE)) + break; + state->handler = doctype0; + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static int PTRCALL +prolog2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PI: + return XML_ROLE_PI; + case XML_TOK_COMMENT: + return XML_ROLE_COMMENT; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static int PTRCALL +doctype0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = doctype1; + return XML_ROLE_DOCTYPE_NAME; + } + return common(state, tok); +} + +static int PTRCALL +doctype1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = internalSubset; + return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = doctype3; + return XML_ROLE_DOCTYPE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = doctype2; + return XML_ROLE_DOCTYPE_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +doctype2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_LITERAL: + state->handler = doctype3; + return XML_ROLE_DOCTYPE_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +doctype3(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_LITERAL: + state->handler = doctype4; + return XML_ROLE_DOCTYPE_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +doctype4(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = internalSubset; + return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + } + return common(state, tok); +} + +static int PTRCALL +doctype5(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + } + return common(state, tok); +} + +static int PTRCALL +internalSubset(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_ENTITY)) { + state->handler = entity0; + return XML_ROLE_ENTITY_NONE; + } + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_ATTLIST)) { + state->handler = attlist0; + return XML_ROLE_ATTLIST_NONE; + } + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_ELEMENT)) { + state->handler = element0; + return XML_ROLE_ELEMENT_NONE; + } + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_NOTATION)) { + state->handler = notation0; + return XML_ROLE_NOTATION_NONE; + } + break; + case XML_TOK_PI: + return XML_ROLE_PI; + case XML_TOK_COMMENT: + return XML_ROLE_COMMENT; + case XML_TOK_PARAM_ENTITY_REF: + return XML_ROLE_PARAM_ENTITY_REF; + case XML_TOK_CLOSE_BRACKET: + state->handler = doctype5; + return XML_ROLE_DOCTYPE_NONE; + } + return common(state, tok); +} + +#ifdef XML_DTD + +static int PTRCALL +externalSubset0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + state->handler = externalSubset1; + if (tok == XML_TOK_XML_DECL) + return XML_ROLE_TEXT_DECL; + return externalSubset1(state, tok, ptr, end, enc); +} + +static int PTRCALL +externalSubset1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_COND_SECT_OPEN: + state->handler = condSect0; + return XML_ROLE_NONE; + case XML_TOK_COND_SECT_CLOSE: + if (state->includeLevel == 0) + break; + state->includeLevel -= 1; + return XML_ROLE_NONE; + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_BRACKET: + break; + case XML_TOK_NONE: + if (state->includeLevel) + break; + return XML_ROLE_NONE; + default: + return internalSubset(state, tok, ptr, end, enc); + } + return common(state, tok); +} + +#endif /* XML_DTD */ + +static int PTRCALL +entity0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_PERCENT: + state->handler = entity1; + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + state->handler = entity2; + return XML_ROLE_GENERAL_ENTITY_NAME; + } + return common(state, tok); +} + +static int PTRCALL +entity1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + state->handler = entity7; + return XML_ROLE_PARAM_ENTITY_NAME; + } + return common(state, tok); +} + +static int PTRCALL +entity2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = entity4; + return XML_ROLE_ENTITY_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = entity3; + return XML_ROLE_ENTITY_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_ENTITY_NONE; + return XML_ROLE_ENTITY_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +entity3(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity4; + return XML_ROLE_ENTITY_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity4(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity5; + return XML_ROLE_ENTITY_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity5(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_ENTITY_COMPLETE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) { + state->handler = entity6; + return XML_ROLE_ENTITY_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +entity6(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + state->handler = declClose; + state->role_none = XML_ROLE_ENTITY_NONE; + return XML_ROLE_ENTITY_NOTATION_NAME; + } + return common(state, tok); +} + +static int PTRCALL +entity7(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = entity9; + return XML_ROLE_ENTITY_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = entity8; + return XML_ROLE_ENTITY_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_ENTITY_NONE; + return XML_ROLE_ENTITY_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +entity8(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity9; + return XML_ROLE_ENTITY_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity9(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity10; + return XML_ROLE_ENTITY_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity10(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_ENTITY_COMPLETE; + } + return common(state, tok); +} + +static int PTRCALL +notation0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_NAME: + state->handler = notation1; + return XML_ROLE_NOTATION_NAME; + } + return common(state, tok); +} + +static int PTRCALL +notation1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = notation3; + return XML_ROLE_NOTATION_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = notation2; + return XML_ROLE_NOTATION_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +notation2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_LITERAL: + state->handler = notation4; + return XML_ROLE_NOTATION_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +notation3(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_NOTATION_NONE; + return XML_ROLE_NOTATION_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +notation4(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_NOTATION_NONE; + return XML_ROLE_NOTATION_SYSTEM_ID; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_NOTATION_NO_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +attlist0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist1; + return XML_ROLE_ATTLIST_ELEMENT_NAME; + } + return common(state, tok); +} + +static int PTRCALL +attlist1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist2; + return XML_ROLE_ATTRIBUTE_NAME; + } + return common(state, tok); +} + +static int PTRCALL +attlist2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: + { + static const char *types[] = { + KW_CDATA, + KW_ID, + KW_IDREF, + KW_IDREFS, + KW_ENTITY, + KW_ENTITIES, + KW_NMTOKEN, + KW_NMTOKENS, + }; + int i; + for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) + if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { + state->handler = attlist8; + return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; + } + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { + state->handler = attlist5; + return XML_ROLE_ATTLIST_NONE; + } + break; + case XML_TOK_OPEN_PAREN: + state->handler = attlist3; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +static int PTRCALL +attlist3(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NMTOKEN: + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist4; + return XML_ROLE_ATTRIBUTE_ENUM_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +attlist4(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = attlist8; + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_OR: + state->handler = attlist3; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +static int PTRCALL +attlist5(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_OPEN_PAREN: + state->handler = attlist6; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +static int PTRCALL +attlist6(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: + state->handler = attlist7; + return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +attlist7(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = attlist8; + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_OR: + state->handler = attlist6; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +/* default value */ +static int PTRCALL +attlist8(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_POUND_NAME: + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + end, + KW_IMPLIED)) { + state->handler = attlist1; + return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; + } + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + end, + KW_REQUIRED)) { + state->handler = attlist1; + return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; + } + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + end, + KW_FIXED)) { + state->handler = attlist9; + return XML_ROLE_ATTLIST_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = attlist1; + return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +attlist9(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_LITERAL: + state->handler = attlist1; + return XML_ROLE_FIXED_ATTRIBUTE_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +element0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element1; + return XML_ROLE_ELEMENT_NAME; + } + return common(state, tok); +} + +static int PTRCALL +element1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_CONTENT_EMPTY; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_CONTENT_ANY; + } + break; + case XML_TOK_OPEN_PAREN: + state->handler = element2; + state->level = 1; + return XML_ROLE_GROUP_OPEN; + } + return common(state, tok); +} + +static int PTRCALL +element2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_POUND_NAME: + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + end, + KW_PCDATA)) { + state->handler = element3; + return XML_ROLE_CONTENT_PCDATA; + } + break; + case XML_TOK_OPEN_PAREN: + state->level = 2; + state->handler = element6; + return XML_ROLE_GROUP_OPEN; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT; + case XML_TOK_NAME_QUESTION: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_OPT; + case XML_TOK_NAME_ASTERISK: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_REP; + case XML_TOK_NAME_PLUS: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_PLUS; + } + return common(state, tok); +} + +static int PTRCALL +element3(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_GROUP_CLOSE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_OR: + state->handler = element4; + return XML_ROLE_ELEMENT_NONE; + } + return common(state, tok); +} + +static int PTRCALL +element4(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element5; + return XML_ROLE_CONTENT_ELEMENT; + } + return common(state, tok); +} + +static int PTRCALL +element5(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_OR: + state->handler = element4; + return XML_ROLE_ELEMENT_NONE; + } + return common(state, tok); +} + +static int PTRCALL +element6(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_OPEN_PAREN: + state->level += 1; + return XML_ROLE_GROUP_OPEN; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT; + case XML_TOK_NAME_QUESTION: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_OPT; + case XML_TOK_NAME_ASTERISK: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_REP; + case XML_TOK_NAME_PLUS: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_PLUS; + } + return common(state, tok); +} + +static int PTRCALL +element7(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_CLOSE_PAREN: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_CLOSE_PAREN_QUESTION: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE_OPT; + case XML_TOK_CLOSE_PAREN_PLUS: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE_PLUS; + case XML_TOK_COMMA: + state->handler = element6; + return XML_ROLE_GROUP_SEQUENCE; + case XML_TOK_OR: + state->handler = element6; + return XML_ROLE_GROUP_CHOICE; + } + return common(state, tok); +} + +#ifdef XML_DTD + +static int PTRCALL +condSect0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) { + state->handler = condSect1; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) { + state->handler = condSect2; + return XML_ROLE_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +condSect1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + state->includeLevel += 1; + return XML_ROLE_NONE; + } + return common(state, tok); +} + +static int PTRCALL +condSect2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + return XML_ROLE_IGNORE_SECT; + } + return common(state, tok); +} + +#endif /* XML_DTD */ + +static int PTRCALL +declClose(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return state->role_none; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return state->role_none; + } + return common(state, tok); +} + +static int PTRCALL +error(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + return XML_ROLE_NONE; +} + +static int FASTCALL +common(PROLOG_STATE *state, int tok) +{ +#ifdef XML_DTD + if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) + return XML_ROLE_INNER_PARAM_ENTITY_REF; +#endif + state->handler = error; + return XML_ROLE_ERROR; +} + +void +XmlPrologStateInit(PROLOG_STATE *state) +{ + state->handler = prolog0; +#ifdef XML_DTD + state->documentEntity = 1; + state->includeLevel = 0; + state->inEntityValue = 0; +#endif /* XML_DTD */ +} + +#ifdef XML_DTD + +void +XmlPrologStateInitExternalEntity(PROLOG_STATE *state) +{ + state->handler = externalSubset0; + state->documentEntity = 0; + state->includeLevel = 0; +} + +#endif /* XML_DTD */ diff --git a/macosx/expat/xmlrole.h b/macosx/expat/xmlrole.h new file mode 100644 index 0000000..4dd9f06 --- /dev/null +++ b/macosx/expat/xmlrole.h @@ -0,0 +1,114 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef XmlRole_INCLUDED +#define XmlRole_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt +#endif + +#include "xmltok.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + XML_ROLE_ERROR = -1, + XML_ROLE_NONE = 0, + XML_ROLE_XML_DECL, + XML_ROLE_INSTANCE_START, + XML_ROLE_DOCTYPE_NONE, + XML_ROLE_DOCTYPE_NAME, + XML_ROLE_DOCTYPE_SYSTEM_ID, + XML_ROLE_DOCTYPE_PUBLIC_ID, + XML_ROLE_DOCTYPE_INTERNAL_SUBSET, + XML_ROLE_DOCTYPE_CLOSE, + XML_ROLE_GENERAL_ENTITY_NAME, + XML_ROLE_PARAM_ENTITY_NAME, + XML_ROLE_ENTITY_NONE, + XML_ROLE_ENTITY_VALUE, + XML_ROLE_ENTITY_SYSTEM_ID, + XML_ROLE_ENTITY_PUBLIC_ID, + XML_ROLE_ENTITY_COMPLETE, + XML_ROLE_ENTITY_NOTATION_NAME, + XML_ROLE_NOTATION_NONE, + XML_ROLE_NOTATION_NAME, + XML_ROLE_NOTATION_SYSTEM_ID, + XML_ROLE_NOTATION_NO_SYSTEM_ID, + XML_ROLE_NOTATION_PUBLIC_ID, + XML_ROLE_ATTRIBUTE_NAME, + XML_ROLE_ATTRIBUTE_TYPE_CDATA, + XML_ROLE_ATTRIBUTE_TYPE_ID, + XML_ROLE_ATTRIBUTE_TYPE_IDREF, + XML_ROLE_ATTRIBUTE_TYPE_IDREFS, + XML_ROLE_ATTRIBUTE_TYPE_ENTITY, + XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, + XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, + XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, + XML_ROLE_ATTRIBUTE_ENUM_VALUE, + XML_ROLE_ATTRIBUTE_NOTATION_VALUE, + XML_ROLE_ATTLIST_NONE, + XML_ROLE_ATTLIST_ELEMENT_NAME, + XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, + XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, + XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, + XML_ROLE_FIXED_ATTRIBUTE_VALUE, + XML_ROLE_ELEMENT_NONE, + XML_ROLE_ELEMENT_NAME, + XML_ROLE_CONTENT_ANY, + XML_ROLE_CONTENT_EMPTY, + XML_ROLE_CONTENT_PCDATA, + XML_ROLE_GROUP_OPEN, + XML_ROLE_GROUP_CLOSE, + XML_ROLE_GROUP_CLOSE_REP, + XML_ROLE_GROUP_CLOSE_OPT, + XML_ROLE_GROUP_CLOSE_PLUS, + XML_ROLE_GROUP_CHOICE, + XML_ROLE_GROUP_SEQUENCE, + XML_ROLE_CONTENT_ELEMENT, + XML_ROLE_CONTENT_ELEMENT_REP, + XML_ROLE_CONTENT_ELEMENT_OPT, + XML_ROLE_CONTENT_ELEMENT_PLUS, + XML_ROLE_PI, + XML_ROLE_COMMENT, +#ifdef XML_DTD + XML_ROLE_TEXT_DECL, + XML_ROLE_IGNORE_SECT, + XML_ROLE_INNER_PARAM_ENTITY_REF, +#endif /* XML_DTD */ + XML_ROLE_PARAM_ENTITY_REF +}; + +typedef struct prolog_state { + int (PTRCALL *handler) (struct prolog_state *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc); + unsigned level; + int role_none; +#ifdef XML_DTD + unsigned includeLevel; + int documentEntity; + int inEntityValue; +#endif /* XML_DTD */ +} PROLOG_STATE; + +void XmlPrologStateInit(PROLOG_STATE *); +#ifdef XML_DTD +void XmlPrologStateInitExternalEntity(PROLOG_STATE *); +#endif /* XML_DTD */ + +#define XmlTokenRole(state, tok, ptr, end, enc) \ + (((state)->handler)(state, tok, ptr, end, enc)) + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlRole_INCLUDED */ diff --git a/macosx/expat/xmltok.c b/macosx/expat/xmltok.c new file mode 100644 index 0000000..5f101af --- /dev/null +++ b/macosx/expat/xmltok.c @@ -0,0 +1,1632 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifdef COMPILED_FROM_DSP +#include "winconfig.h" +#elif defined(MACOS_CLASSIC) +#include "macconfig.h" +#else +#include +#endif /* ndef COMPILED_FROM_DSP */ + +#include "internal.h" +#include "xmltok.h" +#include "nametab.h" + +#ifdef XML_DTD +#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) +#else +#define IGNORE_SECTION_TOK_VTABLE /* as nothing */ +#endif + +#define VTABLE1 \ + { PREFIX(prologTok), PREFIX(contentTok), \ + PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \ + { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ + PREFIX(sameName), \ + PREFIX(nameMatchesAscii), \ + PREFIX(nameLength), \ + PREFIX(skipS), \ + PREFIX(getAtts), \ + PREFIX(charRefNumber), \ + PREFIX(predefinedEntityName), \ + PREFIX(updatePosition), \ + PREFIX(isPublicId) + +#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) + +#define UCS2_GET_NAMING(pages, hi, lo) \ + (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F))) + +/* A 2 byte UTF-8 representation splits the characters 11 bits between + the bottom 5 and 6 bits of the bytes. We need 8 bits to index into + pages, 3 bits to add to that index and 5 bits to generate the mask. +*/ +#define UTF8_GET_NAMING2(pages, byte) \ + (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + + ((((byte)[0]) & 3) << 1) \ + + ((((byte)[1]) >> 5) & 1)] \ + & (1 << (((byte)[1]) & 0x1F))) + +/* A 3 byte UTF-8 representation splits the characters 16 bits between + the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index + into pages, 3 bits to add to that index and 5 bits to generate the + mask. +*/ +#define UTF8_GET_NAMING3(pages, byte) \ + (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ + + ((((byte)[1]) >> 2) & 0xF)] \ + << 3) \ + + ((((byte)[1]) & 3) << 1) \ + + ((((byte)[2]) >> 5) & 1)] \ + & (1 << (((byte)[2]) & 0x1F))) + +#define UTF8_GET_NAMING(pages, p, n) \ + ((n) == 2 \ + ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ + : ((n) == 3 \ + ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \ + : 0)) + +/* Detection of invalid UTF-8 sequences is based on Table 3.1B + of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/ + with the additional restriction of not allowing the Unicode + code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE). + Implementation details: + (A & 0x80) == 0 means A < 0x80 + and + (A & 0xC0) == 0xC0 means A > 0xBF +*/ + +#define UTF8_INVALID2(p) \ + ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0) + +#define UTF8_INVALID3(p) \ + (((p)[2] & 0x80) == 0 \ + || \ + ((*p) == 0xEF && (p)[1] == 0xBF \ + ? \ + (p)[2] > 0xBD \ + : \ + ((p)[2] & 0xC0) == 0xC0) \ + || \ + ((*p) == 0xE0 \ + ? \ + (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ + : \ + ((p)[1] & 0x80) == 0 \ + || \ + ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) + +#define UTF8_INVALID4(p) \ + (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \ + || \ + ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \ + || \ + ((*p) == 0xF0 \ + ? \ + (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ + : \ + ((p)[1] & 0x80) == 0 \ + || \ + ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) + +static int PTRFASTCALL +isNever(const ENCODING *enc, const char *p) +{ + return 0; +} + +static int PTRFASTCALL +utf8_isName2(const ENCODING *enc, const char *p) +{ + return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isName3(const ENCODING *enc, const char *p) +{ + return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); +} + +#define utf8_isName4 isNever + +static int PTRFASTCALL +utf8_isNmstrt2(const ENCODING *enc, const char *p) +{ + return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isNmstrt3(const ENCODING *enc, const char *p) +{ + return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); +} + +#define utf8_isNmstrt4 isNever + +static int PTRFASTCALL +utf8_isInvalid2(const ENCODING *enc, const char *p) +{ + return UTF8_INVALID2((const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isInvalid3(const ENCODING *enc, const char *p) +{ + return UTF8_INVALID3((const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isInvalid4(const ENCODING *enc, const char *p) +{ + return UTF8_INVALID4((const unsigned char *)p); +} + +struct normal_encoding { + ENCODING enc; + unsigned char type[256]; +#ifdef XML_MIN_SIZE + int (PTRFASTCALL *byteType)(const ENCODING *, const char *); + int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *); + int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *); + int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *); + int (PTRCALL *charMatches)(const ENCODING *, const char *, int); +#endif /* XML_MIN_SIZE */ + int (PTRFASTCALL *isName2)(const ENCODING *, const char *); + int (PTRFASTCALL *isName3)(const ENCODING *, const char *); + int (PTRFASTCALL *isName4)(const ENCODING *, const char *); + int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *); + int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *); + int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *); + int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *); + int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *); + int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *); +}; + +#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *) (enc)) + +#ifdef XML_MIN_SIZE + +#define STANDARD_VTABLE(E) \ + E ## byteType, \ + E ## isNameMin, \ + E ## isNmstrtMin, \ + E ## byteToAscii, \ + E ## charMatches, + +#else + +#define STANDARD_VTABLE(E) /* as nothing */ + +#endif + +#define NORMAL_VTABLE(E) \ + E ## isName2, \ + E ## isName3, \ + E ## isName4, \ + E ## isNmstrt2, \ + E ## isNmstrt3, \ + E ## isNmstrt4, \ + E ## isInvalid2, \ + E ## isInvalid3, \ + E ## isInvalid4 + +static int FASTCALL checkCharRefNumber(int); + +#include "xmltok_impl.h" +#include "ascii.h" + +#ifdef XML_MIN_SIZE +#define sb_isNameMin isNever +#define sb_isNmstrtMin isNever +#endif + +#ifdef XML_MIN_SIZE +#define MINBPC(enc) ((enc)->minBytesPerChar) +#else +/* minimum bytes per character */ +#define MINBPC(enc) 1 +#endif + +#define SB_BYTE_TYPE(enc, p) \ + (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) + +#ifdef XML_MIN_SIZE +static int PTRFASTCALL +sb_byteType(const ENCODING *enc, const char *p) +{ + return SB_BYTE_TYPE(enc, p); +} +#define BYTE_TYPE(enc, p) \ + (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) +#else +#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) +#endif + +#ifdef XML_MIN_SIZE +#define BYTE_TO_ASCII(enc, p) \ + (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) +static int PTRFASTCALL +sb_byteToAscii(const ENCODING *enc, const char *p) +{ + return *p; +} +#else +#define BYTE_TO_ASCII(enc, p) (*(p)) +#endif + +#define IS_NAME_CHAR(enc, p, n) \ + (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p)) +#define IS_NMSTRT_CHAR(enc, p, n) \ + (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p)) +#define IS_INVALID_CHAR(enc, p, n) \ + (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p)) + +#ifdef XML_MIN_SIZE +#define IS_NAME_CHAR_MINBPC(enc, p) \ + (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) \ + (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) +#else +#define IS_NAME_CHAR_MINBPC(enc, p) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) +#endif + +#ifdef XML_MIN_SIZE +#define CHAR_MATCHES(enc, p, c) \ + (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) +static int PTRCALL +sb_charMatches(const ENCODING *enc, const char *p, int c) +{ + return *p == c; +} +#else +/* c is an ASCII character */ +#define CHAR_MATCHES(enc, p, c) (*(p) == c) +#endif + +#define PREFIX(ident) normal_ ## ident +#include "xmltok_impl.c" + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ + UTF8_cval1 = 0x00, + UTF8_cval2 = 0xc0, + UTF8_cval3 = 0xe0, + UTF8_cval4 = 0xf0 +}; + +static void PTRCALL +utf8_toUtf8(const ENCODING *enc, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + char *to; + const char *from; + if (fromLim - *fromP > toLim - *toP) { + /* Avoid copying partial characters. */ + for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--) + if (((unsigned char)fromLim[-1] & 0xc0) != 0x80) + break; + } + for (to = *toP, from = *fromP; from != fromLim; from++, to++) + *to = *from; + *fromP = from; + *toP = to; +} + +static void PTRCALL +utf8_toUtf16(const ENCODING *enc, + const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) +{ + unsigned short *to = *toP; + const char *from = *fromP; + while (from != fromLim && to != toLim) { + switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { + case BT_LEAD2: + *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); + from += 2; + break; + case BT_LEAD3: + *to++ = (unsigned short)(((from[0] & 0xf) << 12) + | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); + from += 3; + break; + case BT_LEAD4: + { + unsigned long n; + if (to + 1 == toLim) + goto after; + n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) + | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); + n -= 0x10000; + to[0] = (unsigned short)((n >> 10) | 0xD800); + to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); + to += 2; + from += 4; + } + break; + default: + *to++ = *from++; + break; + } + } +after: + *fromP = from; + *toP = to; +} + +#ifdef XML_NS +static const struct normal_encoding utf8_encoding_ns = { + { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, + { +#include "asciitab.h" +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; +#endif + +static const struct normal_encoding utf8_encoding = { + { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; + +#ifdef XML_NS + +static const struct normal_encoding internal_utf8_encoding_ns = { + { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, + { +#include "iasciitab.h" +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; + +#endif + +static const struct normal_encoding internal_utf8_encoding = { + { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, + { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; + +static void PTRCALL +latin1_toUtf8(const ENCODING *enc, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + for (;;) { + unsigned char c; + if (*fromP == fromLim) + break; + c = (unsigned char)**fromP; + if (c & 0x80) { + if (toLim - *toP < 2) + break; + *(*toP)++ = (char)((c >> 6) | UTF8_cval2); + *(*toP)++ = (char)((c & 0x3f) | 0x80); + (*fromP)++; + } + else { + if (*toP == toLim) + break; + *(*toP)++ = *(*fromP)++; + } + } +} + +static void PTRCALL +latin1_toUtf16(const ENCODING *enc, + const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) +{ + while (*fromP != fromLim && *toP != toLim) + *(*toP)++ = (unsigned char)*(*fromP)++; +} + +#ifdef XML_NS + +static const struct normal_encoding latin1_encoding_ns = { + { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, + { +#include "asciitab.h" +#include "latin1tab.h" + }, + STANDARD_VTABLE(sb_) +}; + +#endif + +static const struct normal_encoding latin1_encoding = { + { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(sb_) +}; + +static void PTRCALL +ascii_toUtf8(const ENCODING *enc, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + while (*fromP != fromLim && *toP != toLim) + *(*toP)++ = *(*fromP)++; +} + +#ifdef XML_NS + +static const struct normal_encoding ascii_encoding_ns = { + { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, + { +#include "asciitab.h" +/* BT_NONXML == 0 */ + }, + STANDARD_VTABLE(sb_) +}; + +#endif + +static const struct normal_encoding ascii_encoding = { + { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +/* BT_NONXML == 0 */ + }, + STANDARD_VTABLE(sb_) +}; + +static int PTRFASTCALL +unicode_byte_type(char hi, char lo) +{ + switch ((unsigned char)hi) { + case 0xD8: case 0xD9: case 0xDA: case 0xDB: + return BT_LEAD4; + case 0xDC: case 0xDD: case 0xDE: case 0xDF: + return BT_TRAIL; + case 0xFF: + switch ((unsigned char)lo) { + case 0xFF: + case 0xFE: + return BT_NONXML; + } + break; + } + return BT_NONASCII; +} + +#define DEFINE_UTF16_TO_UTF8(E) \ +static void PTRCALL \ +E ## toUtf8(const ENCODING *enc, \ + const char **fromP, const char *fromLim, \ + char **toP, const char *toLim) \ +{ \ + const char *from; \ + for (from = *fromP; from != fromLim; from += 2) { \ + int plane; \ + unsigned char lo2; \ + unsigned char lo = GET_LO(from); \ + unsigned char hi = GET_HI(from); \ + switch (hi) { \ + case 0: \ + if (lo < 0x80) { \ + if (*toP == toLim) { \ + *fromP = from; \ + return; \ + } \ + *(*toP)++ = lo; \ + break; \ + } \ + /* fall through */ \ + case 0x1: case 0x2: case 0x3: \ + case 0x4: case 0x5: case 0x6: case 0x7: \ + if (toLim - *toP < 2) { \ + *fromP = from; \ + return; \ + } \ + *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + default: \ + if (toLim - *toP < 3) { \ + *fromP = from; \ + return; \ + } \ + /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ + *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ + *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ + if (toLim - *toP < 4) { \ + *fromP = from; \ + return; \ + } \ + plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ + *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ + *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ + from += 2; \ + lo2 = GET_LO(from); \ + *(*toP)++ = (((lo & 0x3) << 4) \ + | ((GET_HI(from) & 0x3) << 2) \ + | (lo2 >> 6) \ + | 0x80); \ + *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ + break; \ + } \ + } \ + *fromP = from; \ +} + +#define DEFINE_UTF16_TO_UTF16(E) \ +static void PTRCALL \ +E ## toUtf16(const ENCODING *enc, \ + const char **fromP, const char *fromLim, \ + unsigned short **toP, const unsigned short *toLim) \ +{ \ + /* Avoid copying first half only of surrogate */ \ + if (fromLim - *fromP > ((toLim - *toP) << 1) \ + && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \ + fromLim -= 2; \ + for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \ + *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ +} + +#define SET2(ptr, ch) \ + (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8))) +#define GET_LO(ptr) ((unsigned char)(ptr)[0]) +#define GET_HI(ptr) ((unsigned char)(ptr)[1]) + +DEFINE_UTF16_TO_UTF8(little2_) +DEFINE_UTF16_TO_UTF16(little2_) + +#undef SET2 +#undef GET_LO +#undef GET_HI + +#define SET2(ptr, ch) \ + (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF))) +#define GET_LO(ptr) ((unsigned char)(ptr)[1]) +#define GET_HI(ptr) ((unsigned char)(ptr)[0]) + +DEFINE_UTF16_TO_UTF8(big2_) +DEFINE_UTF16_TO_UTF16(big2_) + +#undef SET2 +#undef GET_LO +#undef GET_HI + +#define LITTLE2_BYTE_TYPE(enc, p) \ + ((p)[1] == 0 \ + ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ + : unicode_byte_type((p)[1], (p)[0])) +#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1) +#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c) +#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) +#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) + +#ifdef XML_MIN_SIZE + +static int PTRFASTCALL +little2_byteType(const ENCODING *enc, const char *p) +{ + return LITTLE2_BYTE_TYPE(enc, p); +} + +static int PTRFASTCALL +little2_byteToAscii(const ENCODING *enc, const char *p) +{ + return LITTLE2_BYTE_TO_ASCII(enc, p); +} + +static int PTRCALL +little2_charMatches(const ENCODING *enc, const char *p, int c) +{ + return LITTLE2_CHAR_MATCHES(enc, p, c); +} + +static int PTRFASTCALL +little2_isNameMin(const ENCODING *enc, const char *p) +{ + return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p); +} + +static int PTRFASTCALL +little2_isNmstrtMin(const ENCODING *enc, const char *p) +{ + return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p); +} + +#undef VTABLE +#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 + +#else /* not XML_MIN_SIZE */ + +#undef PREFIX +#define PREFIX(ident) little2_ ## ident +#define MINBPC(enc) 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) +#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) +#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c) +#define IS_NAME_CHAR(enc, p, n) 0 +#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) +#define IS_NMSTRT_CHAR(enc, p, n) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) + +#include "xmltok_impl.c" + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +#endif /* not XML_MIN_SIZE */ + +#ifdef XML_NS + +static const struct normal_encoding little2_encoding_ns = { + { VTABLE, 2, 0, +#if BYTEORDER == 1234 + 1 +#else + 0 +#endif + }, + { +#include "asciitab.h" +#include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) +}; + +#endif + +static const struct normal_encoding little2_encoding = { + { VTABLE, 2, 0, +#if BYTEORDER == 1234 + 1 +#else + 0 +#endif + }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) +}; + +#if BYTEORDER != 4321 + +#ifdef XML_NS + +static const struct normal_encoding internal_little2_encoding_ns = { + { VTABLE, 2, 0, 1 }, + { +#include "iasciitab.h" +#include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) +}; + +#endif + +static const struct normal_encoding internal_little2_encoding = { + { VTABLE, 2, 0, 1 }, + { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) +}; + +#endif + + +#define BIG2_BYTE_TYPE(enc, p) \ + ((p)[0] == 0 \ + ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ + : unicode_byte_type((p)[0], (p)[1])) +#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1) +#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c) +#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) +#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) + +#ifdef XML_MIN_SIZE + +static int PTRFASTCALL +big2_byteType(const ENCODING *enc, const char *p) +{ + return BIG2_BYTE_TYPE(enc, p); +} + +static int PTRFASTCALL +big2_byteToAscii(const ENCODING *enc, const char *p) +{ + return BIG2_BYTE_TO_ASCII(enc, p); +} + +static int PTRCALL +big2_charMatches(const ENCODING *enc, const char *p, int c) +{ + return BIG2_CHAR_MATCHES(enc, p, c); +} + +static int PTRFASTCALL +big2_isNameMin(const ENCODING *enc, const char *p) +{ + return BIG2_IS_NAME_CHAR_MINBPC(enc, p); +} + +static int PTRFASTCALL +big2_isNmstrtMin(const ENCODING *enc, const char *p) +{ + return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p); +} + +#undef VTABLE +#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 + +#else /* not XML_MIN_SIZE */ + +#undef PREFIX +#define PREFIX(ident) big2_ ## ident +#define MINBPC(enc) 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) +#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) +#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c) +#define IS_NAME_CHAR(enc, p, n) 0 +#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p) +#define IS_NMSTRT_CHAR(enc, p, n) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) + +#include "xmltok_impl.c" + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +#endif /* not XML_MIN_SIZE */ + +#ifdef XML_NS + +static const struct normal_encoding big2_encoding_ns = { + { VTABLE, 2, 0, +#if BYTEORDER == 4321 + 1 +#else + 0 +#endif + }, + { +#include "asciitab.h" +#include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) +}; + +#endif + +static const struct normal_encoding big2_encoding = { + { VTABLE, 2, 0, +#if BYTEORDER == 4321 + 1 +#else + 0 +#endif + }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) +}; + +#if BYTEORDER != 1234 + +#ifdef XML_NS + +static const struct normal_encoding internal_big2_encoding_ns = { + { VTABLE, 2, 0, 1 }, + { +#include "iasciitab.h" +#include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) +}; + +#endif + +static const struct normal_encoding internal_big2_encoding = { + { VTABLE, 2, 0, 1 }, + { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) +}; + +#endif + +#undef PREFIX + +static int FASTCALL +streqci(const char *s1, const char *s2) +{ + for (;;) { + char c1 = *s1++; + char c2 = *s2++; + if (ASCII_a <= c1 && c1 <= ASCII_z) + c1 += ASCII_A - ASCII_a; + if (ASCII_a <= c2 && c2 <= ASCII_z) + c2 += ASCII_A - ASCII_a; + if (c1 != c2) + return 0; + if (!c1) + break; + } + return 1; +} + +static void PTRCALL +initUpdatePosition(const ENCODING *enc, const char *ptr, + const char *end, POSITION *pos) +{ + normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); +} + +static int +toAscii(const ENCODING *enc, const char *ptr, const char *end) +{ + char buf[1]; + char *p = buf; + XmlUtf8Convert(enc, &ptr, end, &p, p + 1); + if (p == buf) + return -1; + else + return buf[0]; +} + +static int FASTCALL +isSpace(int c) +{ + switch (c) { + case 0x20: + case 0xD: + case 0xA: + case 0x9: + return 1; + } + return 0; +} + +/* Return 1 if there's just optional white space or there's an S + followed by name=val. +*/ +static int +parsePseudoAttribute(const ENCODING *enc, + const char *ptr, + const char *end, + const char **namePtr, + const char **nameEndPtr, + const char **valPtr, + const char **nextTokPtr) +{ + int c; + char open; + if (ptr == end) { + *namePtr = NULL; + return 1; + } + if (!isSpace(toAscii(enc, ptr, end))) { + *nextTokPtr = ptr; + return 0; + } + do { + ptr += enc->minBytesPerChar; + } while (isSpace(toAscii(enc, ptr, end))); + if (ptr == end) { + *namePtr = NULL; + return 1; + } + *namePtr = ptr; + for (;;) { + c = toAscii(enc, ptr, end); + if (c == -1) { + *nextTokPtr = ptr; + return 0; + } + if (c == ASCII_EQUALS) { + *nameEndPtr = ptr; + break; + } + if (isSpace(c)) { + *nameEndPtr = ptr; + do { + ptr += enc->minBytesPerChar; + } while (isSpace(c = toAscii(enc, ptr, end))); + if (c != ASCII_EQUALS) { + *nextTokPtr = ptr; + return 0; + } + break; + } + ptr += enc->minBytesPerChar; + } + if (ptr == *namePtr) { + *nextTokPtr = ptr; + return 0; + } + ptr += enc->minBytesPerChar; + c = toAscii(enc, ptr, end); + while (isSpace(c)) { + ptr += enc->minBytesPerChar; + c = toAscii(enc, ptr, end); + } + if (c != ASCII_QUOT && c != ASCII_APOS) { + *nextTokPtr = ptr; + return 0; + } + open = (char)c; + ptr += enc->minBytesPerChar; + *valPtr = ptr; + for (;; ptr += enc->minBytesPerChar) { + c = toAscii(enc, ptr, end); + if (c == open) + break; + if (!(ASCII_a <= c && c <= ASCII_z) + && !(ASCII_A <= c && c <= ASCII_Z) + && !(ASCII_0 <= c && c <= ASCII_9) + && c != ASCII_PERIOD + && c != ASCII_MINUS + && c != ASCII_UNDERSCORE) { + *nextTokPtr = ptr; + return 0; + } + } + *nextTokPtr = ptr + enc->minBytesPerChar; + return 1; +} + +static const char KW_version[] = { + ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0' +}; + +static const char KW_encoding[] = { + ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0' +}; + +static const char KW_standalone[] = { + ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, + ASCII_n, ASCII_e, '\0' +}; + +static const char KW_yes[] = { + ASCII_y, ASCII_e, ASCII_s, '\0' +}; + +static const char KW_no[] = { + ASCII_n, ASCII_o, '\0' +}; + +static int +doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, + const char *, + const char *), + int isGeneralTextEntity, + const ENCODING *enc, + const char *ptr, + const char *end, + const char **badPtr, + const char **versionPtr, + const char **versionEndPtr, + const char **encodingName, + const ENCODING **encoding, + int *standalone) +{ + const char *val = NULL; + const char *name = NULL; + const char *nameEnd = NULL; + ptr += 5 * enc->minBytesPerChar; + end -= 2 * enc->minBytesPerChar; + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) + || !name) { + *badPtr = ptr; + return 0; + } + if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { + if (!isGeneralTextEntity) { + *badPtr = name; + return 0; + } + } + else { + if (versionPtr) + *versionPtr = val; + if (versionEndPtr) + *versionEndPtr = ptr; + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { + *badPtr = ptr; + return 0; + } + if (!name) { + if (isGeneralTextEntity) { + /* a TextDecl must have an EncodingDecl */ + *badPtr = ptr; + return 0; + } + return 1; + } + } + if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { + int c = toAscii(enc, val, end); + if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) { + *badPtr = val; + return 0; + } + if (encodingName) + *encodingName = val; + if (encoding) + *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { + *badPtr = ptr; + return 0; + } + if (!name) + return 1; + } + if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) + || isGeneralTextEntity) { + *badPtr = name; + return 0; + } + if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { + if (standalone) + *standalone = 1; + } + else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { + if (standalone) + *standalone = 0; + } + else { + *badPtr = val; + return 0; + } + while (isSpace(toAscii(enc, ptr, end))) + ptr += enc->minBytesPerChar; + if (ptr != end) { + *badPtr = ptr; + return 0; + } + return 1; +} + +static int FASTCALL +checkCharRefNumber(int result) +{ + switch (result >> 8) { + case 0xD8: case 0xD9: case 0xDA: case 0xDB: + case 0xDC: case 0xDD: case 0xDE: case 0xDF: + return -1; + case 0: + if (latin1_encoding.type[result] == BT_NONXML) + return -1; + break; + case 0xFF: + if (result == 0xFFFE || result == 0xFFFF) + return -1; + break; + } + return result; +} + +int FASTCALL +XmlUtf8Encode(int c, char *buf) +{ + enum { + /* minN is minimum legal resulting value for N byte sequence */ + min2 = 0x80, + min3 = 0x800, + min4 = 0x10000 + }; + + if (c < 0) + return 0; + if (c < min2) { + buf[0] = (char)(c | UTF8_cval1); + return 1; + } + if (c < min3) { + buf[0] = (char)((c >> 6) | UTF8_cval2); + buf[1] = (char)((c & 0x3f) | 0x80); + return 2; + } + if (c < min4) { + buf[0] = (char)((c >> 12) | UTF8_cval3); + buf[1] = (char)(((c >> 6) & 0x3f) | 0x80); + buf[2] = (char)((c & 0x3f) | 0x80); + return 3; + } + if (c < 0x110000) { + buf[0] = (char)((c >> 18) | UTF8_cval4); + buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); + buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); + buf[3] = (char)((c & 0x3f) | 0x80); + return 4; + } + return 0; +} + +int FASTCALL +XmlUtf16Encode(int charNum, unsigned short *buf) +{ + if (charNum < 0) + return 0; + if (charNum < 0x10000) { + buf[0] = (unsigned short)charNum; + return 1; + } + if (charNum < 0x110000) { + charNum -= 0x10000; + buf[0] = (unsigned short)((charNum >> 10) + 0xD800); + buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00); + return 2; + } + return 0; +} + +struct unknown_encoding { + struct normal_encoding normal; + int (*convert)(void *userData, const char *p); + void *userData; + unsigned short utf16[256]; + char utf8[256][4]; +}; + +#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *) (enc)) + +int +XmlSizeOfUnknownEncoding(void) +{ + return sizeof(struct unknown_encoding); +} + +static int PTRFASTCALL +unknown_isName(const ENCODING *enc, const char *p) +{ + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + int c = uenc->convert(uenc->userData, p); + if (c & ~0xFFFF) + return 0; + return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); +} + +static int PTRFASTCALL +unknown_isNmstrt(const ENCODING *enc, const char *p) +{ + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + int c = uenc->convert(uenc->userData, p); + if (c & ~0xFFFF) + return 0; + return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); +} + +static int PTRFASTCALL +unknown_isInvalid(const ENCODING *enc, const char *p) +{ + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + int c = uenc->convert(uenc->userData, p); + return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; +} + +static void PTRCALL +unknown_toUtf8(const ENCODING *enc, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + char buf[XML_UTF8_ENCODE_MAX]; + for (;;) { + const char *utf8; + int n; + if (*fromP == fromLim) + break; + utf8 = uenc->utf8[(unsigned char)**fromP]; + n = *utf8++; + if (n == 0) { + int c = uenc->convert(uenc->userData, *fromP); + n = XmlUtf8Encode(c, buf); + if (n > toLim - *toP) + break; + utf8 = buf; + *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] + - (BT_LEAD2 - 2)); + } + else { + if (n > toLim - *toP) + break; + (*fromP)++; + } + do { + *(*toP)++ = *utf8++; + } while (--n != 0); + } +} + +static void PTRCALL +unknown_toUtf16(const ENCODING *enc, + const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) +{ + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + while (*fromP != fromLim && *toP != toLim) { + unsigned short c = uenc->utf16[(unsigned char)**fromP]; + if (c == 0) { + c = (unsigned short) + uenc->convert(uenc->userData, *fromP); + *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] + - (BT_LEAD2 - 2)); + } + else + (*fromP)++; + *(*toP)++ = c; + } +} + +ENCODING * +XmlInitUnknownEncoding(void *mem, + int *table, + CONVERTER convert, + void *userData) +{ + int i; + struct unknown_encoding *e = (struct unknown_encoding *)mem; + for (i = 0; i < (int)sizeof(struct normal_encoding); i++) + ((char *)mem)[i] = ((char *)&latin1_encoding)[i]; + for (i = 0; i < 128; i++) + if (latin1_encoding.type[i] != BT_OTHER + && latin1_encoding.type[i] != BT_NONXML + && table[i] != i) + return 0; + for (i = 0; i < 256; i++) { + int c = table[i]; + if (c == -1) { + e->normal.type[i] = BT_MALFORM; + /* This shouldn't really get used. */ + e->utf16[i] = 0xFFFF; + e->utf8[i][0] = 1; + e->utf8[i][1] = 0; + } + else if (c < 0) { + if (c < -4) + return 0; + e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); + e->utf8[i][0] = 0; + e->utf16[i] = 0; + } + else if (c < 0x80) { + if (latin1_encoding.type[c] != BT_OTHER + && latin1_encoding.type[c] != BT_NONXML + && c != i) + return 0; + e->normal.type[i] = latin1_encoding.type[c]; + e->utf8[i][0] = 1; + e->utf8[i][1] = (char)c; + e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); + } + else if (checkCharRefNumber(c) < 0) { + e->normal.type[i] = BT_NONXML; + /* This shouldn't really get used. */ + e->utf16[i] = 0xFFFF; + e->utf8[i][0] = 1; + e->utf8[i][1] = 0; + } + else { + if (c > 0xFFFF) + return 0; + if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) + e->normal.type[i] = BT_NMSTRT; + else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) + e->normal.type[i] = BT_NAME; + else + e->normal.type[i] = BT_OTHER; + e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); + e->utf16[i] = (unsigned short)c; + } + } + e->userData = userData; + e->convert = convert; + if (convert) { + e->normal.isName2 = unknown_isName; + e->normal.isName3 = unknown_isName; + e->normal.isName4 = unknown_isName; + e->normal.isNmstrt2 = unknown_isNmstrt; + e->normal.isNmstrt3 = unknown_isNmstrt; + e->normal.isNmstrt4 = unknown_isNmstrt; + e->normal.isInvalid2 = unknown_isInvalid; + e->normal.isInvalid3 = unknown_isInvalid; + e->normal.isInvalid4 = unknown_isInvalid; + } + e->normal.enc.utf8Convert = unknown_toUtf8; + e->normal.enc.utf16Convert = unknown_toUtf16; + return &(e->normal.enc); +} + +/* If this enumeration is changed, getEncodingIndex and encodings +must also be changed. */ +enum { + UNKNOWN_ENC = -1, + ISO_8859_1_ENC = 0, + US_ASCII_ENC, + UTF_8_ENC, + UTF_16_ENC, + UTF_16BE_ENC, + UTF_16LE_ENC, + /* must match encodingNames up to here */ + NO_ENC +}; + +static const char KW_ISO_8859_1[] = { + ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, + ASCII_MINUS, ASCII_1, '\0' +}; +static const char KW_US_ASCII[] = { + ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, + '\0' +}; +static const char KW_UTF_8[] = { + ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0' +}; +static const char KW_UTF_16[] = { + ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0' +}; +static const char KW_UTF_16BE[] = { + ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, + '\0' +}; +static const char KW_UTF_16LE[] = { + ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, + '\0' +}; + +static int FASTCALL +getEncodingIndex(const char *name) +{ + static const char *encodingNames[] = { + KW_ISO_8859_1, + KW_US_ASCII, + KW_UTF_8, + KW_UTF_16, + KW_UTF_16BE, + KW_UTF_16LE, + }; + int i; + if (name == NULL) + return NO_ENC; + for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++) + if (streqci(name, encodingNames[i])) + return i; + return UNKNOWN_ENC; +} + +/* For binary compatibility, we store the index of the encoding + specified at initialization in the isUtf16 member. +*/ + +#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) +#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) + +/* This is what detects the encoding. encodingTable maps from + encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of + the external (protocol) specified encoding; state is + XML_CONTENT_STATE if we're parsing an external text entity, and + XML_PROLOG_STATE otherwise. +*/ + + +static int +initScan(const ENCODING **encodingTable, + const INIT_ENCODING *enc, + int state, + const char *ptr, + const char *end, + const char **nextTokPtr) +{ + const ENCODING **encPtr; + + if (ptr == end) + return XML_TOK_NONE; + encPtr = enc->encPtr; + if (ptr + 1 == end) { + /* only a single byte available for auto-detection */ +#ifndef XML_DTD /* FIXME */ + /* a well-formed document entity must have more than one byte */ + if (state != XML_CONTENT_STATE) + return XML_TOK_PARTIAL; +#endif + /* so we're parsing an external text entity... */ + /* if UTF-16 was externally specified, then we need at least 2 bytes */ + switch (INIT_ENC_INDEX(enc)) { + case UTF_16_ENC: + case UTF_16LE_ENC: + case UTF_16BE_ENC: + return XML_TOK_PARTIAL; + } + switch ((unsigned char)*ptr) { + case 0xFE: + case 0xFF: + case 0xEF: /* possibly first byte of UTF-8 BOM */ + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC + && state == XML_CONTENT_STATE) + break; + /* fall through */ + case 0x00: + case 0x3C: + return XML_TOK_PARTIAL; + } + } + else { + switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { + case 0xFEFF: + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC + && state == XML_CONTENT_STATE) + break; + *nextTokPtr = ptr + 2; + *encPtr = encodingTable[UTF_16BE_ENC]; + return XML_TOK_BOM; + /* 00 3C is handled in the default case */ + case 0x3C00: + if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC + || INIT_ENC_INDEX(enc) == UTF_16_ENC) + && state == XML_CONTENT_STATE) + break; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + case 0xFFFE: + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC + && state == XML_CONTENT_STATE) + break; + *nextTokPtr = ptr + 2; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XML_TOK_BOM; + case 0xEFBB: + /* Maybe a UTF-8 BOM (EF BB BF) */ + /* If there's an explicitly specified (external) encoding + of ISO-8859-1 or some flavour of UTF-16 + and this is an external text entity, + don't look for the BOM, + because it might be a legal data. + */ + if (state == XML_CONTENT_STATE) { + int e = INIT_ENC_INDEX(enc); + if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC + || e == UTF_16LE_ENC || e == UTF_16_ENC) + break; + } + if (ptr + 2 == end) + return XML_TOK_PARTIAL; + if ((unsigned char)ptr[2] == 0xBF) { + *nextTokPtr = ptr + 3; + *encPtr = encodingTable[UTF_8_ENC]; + return XML_TOK_BOM; + } + break; + default: + if (ptr[0] == '\0') { + /* 0 isn't a legal data character. Furthermore a document + entity can only start with ASCII characters. So the only + way this can fail to be big-endian UTF-16 if it it's an + external parsed general entity that's labelled as + UTF-16LE. + */ + if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) + break; + *encPtr = encodingTable[UTF_16BE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + } + else if (ptr[1] == '\0') { + /* We could recover here in the case: + - parsing an external entity + - second byte is 0 + - no externally specified encoding + - no encoding declaration + by assuming UTF-16LE. But we don't, because this would mean when + presented just with a single byte, we couldn't reliably determine + whether we needed further bytes. + */ + if (state == XML_CONTENT_STATE) + break; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + } + break; + } + } + *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); +} + + +#define NS(x) x +#define ns(x) x +#include "xmltok_ns.c" +#undef NS +#undef ns + +#ifdef XML_NS + +#define NS(x) x ## NS +#define ns(x) x ## _ns + +#include "xmltok_ns.c" + +#undef NS +#undef ns + +ENCODING * +XmlInitUnknownEncodingNS(void *mem, + int *table, + CONVERTER convert, + void *userData) +{ + ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); + if (enc) + ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; + return enc; +} + +#endif /* XML_NS */ diff --git a/macosx/expat/xmltok.h b/macosx/expat/xmltok.h new file mode 100644 index 0000000..3d776be --- /dev/null +++ b/macosx/expat/xmltok.h @@ -0,0 +1,315 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef XmlTok_INCLUDED +#define XmlTok_INCLUDED 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following token may be returned by XmlContentTok */ +#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be + start of illegal ]]> sequence */ +/* The following tokens may be returned by both XmlPrologTok and + XmlContentTok. +*/ +#define XML_TOK_NONE -4 /* The string to be scanned is empty */ +#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan; + might be part of CRLF sequence */ +#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ +#define XML_TOK_PARTIAL -1 /* only part of a token */ +#define XML_TOK_INVALID 0 + +/* The following tokens are returned by XmlContentTok; some are also + returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok. +*/ +#define XML_TOK_START_TAG_WITH_ATTS 1 +#define XML_TOK_START_TAG_NO_ATTS 2 +#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag */ +#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 +#define XML_TOK_END_TAG 5 +#define XML_TOK_DATA_CHARS 6 +#define XML_TOK_DATA_NEWLINE 7 +#define XML_TOK_CDATA_SECT_OPEN 8 +#define XML_TOK_ENTITY_REF 9 +#define XML_TOK_CHAR_REF 10 /* numeric character reference */ + +/* The following tokens may be returned by both XmlPrologTok and + XmlContentTok. +*/ +#define XML_TOK_PI 11 /* processing instruction */ +#define XML_TOK_XML_DECL 12 /* XML decl or text decl */ +#define XML_TOK_COMMENT 13 +#define XML_TOK_BOM 14 /* Byte order mark */ + +/* The following tokens are returned only by XmlPrologTok */ +#define XML_TOK_PROLOG_S 15 +#define XML_TOK_DECL_OPEN 16 /* */ +#define XML_TOK_NAME 18 +#define XML_TOK_NMTOKEN 19 +#define XML_TOK_POUND_NAME 20 /* #name */ +#define XML_TOK_OR 21 /* | */ +#define XML_TOK_PERCENT 22 +#define XML_TOK_OPEN_PAREN 23 +#define XML_TOK_CLOSE_PAREN 24 +#define XML_TOK_OPEN_BRACKET 25 +#define XML_TOK_CLOSE_BRACKET 26 +#define XML_TOK_LITERAL 27 +#define XML_TOK_PARAM_ENTITY_REF 28 +#define XML_TOK_INSTANCE_START 29 + +/* The following occur only in element type declarations */ +#define XML_TOK_NAME_QUESTION 30 /* name? */ +#define XML_TOK_NAME_ASTERISK 31 /* name* */ +#define XML_TOK_NAME_PLUS 32 /* name+ */ +#define XML_TOK_COND_SECT_OPEN 33 /* */ +#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ +#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ +#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ +#define XML_TOK_COMMA 38 + +/* The following token is returned only by XmlAttributeValueTok */ +#define XML_TOK_ATTRIBUTE_VALUE_S 39 + +/* The following token is returned only by XmlCdataSectionTok */ +#define XML_TOK_CDATA_SECT_CLOSE 40 + +/* With namespace processing this is returned by XmlPrologTok for a + name with a colon. +*/ +#define XML_TOK_PREFIXED_NAME 41 + +#ifdef XML_DTD +#define XML_TOK_IGNORE_SECT 42 +#endif /* XML_DTD */ + +#ifdef XML_DTD +#define XML_N_STATES 4 +#else /* not XML_DTD */ +#define XML_N_STATES 3 +#endif /* not XML_DTD */ + +#define XML_PROLOG_STATE 0 +#define XML_CONTENT_STATE 1 +#define XML_CDATA_SECTION_STATE 2 +#ifdef XML_DTD +#define XML_IGNORE_SECTION_STATE 3 +#endif /* XML_DTD */ + +#define XML_N_LITERAL_TYPES 2 +#define XML_ATTRIBUTE_VALUE_LITERAL 0 +#define XML_ENTITY_VALUE_LITERAL 1 + +/* The size of the buffer passed to XmlUtf8Encode must be at least this. */ +#define XML_UTF8_ENCODE_MAX 4 +/* The size of the buffer passed to XmlUtf16Encode must be at least this. */ +#define XML_UTF16_ENCODE_MAX 2 + +typedef struct position { + /* first line and first column are 0 not 1 */ + unsigned long lineNumber; + unsigned long columnNumber; +} POSITION; + +typedef struct { + const char *name; + const char *valuePtr; + const char *valueEnd; + char normalized; +} ATTRIBUTE; + +struct encoding; +typedef struct encoding ENCODING; + +typedef int (PTRCALL *SCANNER)(const ENCODING *, + const char *, + const char *, + const char **); + +struct encoding { + SCANNER scanners[XML_N_STATES]; + SCANNER literalScanners[XML_N_LITERAL_TYPES]; + int (PTRCALL *sameName)(const ENCODING *, + const char *, + const char *); + int (PTRCALL *nameMatchesAscii)(const ENCODING *, + const char *, + const char *, + const char *); + int (PTRFASTCALL *nameLength)(const ENCODING *, const char *); + const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *); + int (PTRCALL *getAtts)(const ENCODING *enc, + const char *ptr, + int attsMax, + ATTRIBUTE *atts); + int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr); + int (PTRCALL *predefinedEntityName)(const ENCODING *, + const char *, + const char *); + void (PTRCALL *updatePosition)(const ENCODING *, + const char *ptr, + const char *end, + POSITION *); + int (PTRCALL *isPublicId)(const ENCODING *enc, + const char *ptr, + const char *end, + const char **badPtr); + void (PTRCALL *utf8Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, + char **toP, + const char *toLim); + void (PTRCALL *utf16Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, + unsigned short **toP, + const unsigned short *toLim); + int minBytesPerChar; + char isUtf8; + char isUtf16; +}; + +/* Scan the string starting at ptr until the end of the next complete + token, but do not scan past eptr. Return an integer giving the + type of token. + + Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. + + Return XML_TOK_PARTIAL when the string does not contain a complete + token; nextTokPtr will not be set. + + Return XML_TOK_INVALID when the string does not start a valid + token; nextTokPtr will be set to point to the character which made + the token invalid. + + Otherwise the string starts with a valid token; nextTokPtr will be + set to point to the character following the end of that token. + + Each data character counts as a single token, but adjacent data + characters may be returned together. Similarly for characters in + the prolog outside literals, comments and processing instructions. +*/ + + +#define XmlTok(enc, state, ptr, end, nextTokPtr) \ + (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) + +#define XmlPrologTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) + +#define XmlContentTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) + +#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) + +#ifdef XML_DTD + +#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) + +#endif /* XML_DTD */ + +/* This is used for performing a 2nd-level tokenization on the content + of a literal that has already been returned by XmlTok. +*/ +#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ + (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) + +#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2)) + +#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ + (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) + +#define XmlNameLength(enc, ptr) \ + (((enc)->nameLength)(enc, ptr)) + +#define XmlSkipS(enc, ptr) \ + (((enc)->skipS)(enc, ptr)) + +#define XmlGetAttributes(enc, ptr, attsMax, atts) \ + (((enc)->getAtts)(enc, ptr, attsMax, atts)) + +#define XmlCharRefNumber(enc, ptr) \ + (((enc)->charRefNumber)(enc, ptr)) + +#define XmlPredefinedEntityName(enc, ptr, end) \ + (((enc)->predefinedEntityName)(enc, ptr, end)) + +#define XmlUpdatePosition(enc, ptr, end, pos) \ + (((enc)->updatePosition)(enc, ptr, end, pos)) + +#define XmlIsPublicId(enc, ptr, end, badPtr) \ + (((enc)->isPublicId)(enc, ptr, end, badPtr)) + +#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ + (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) + +#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ + (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) + +typedef struct { + ENCODING initEnc; + const ENCODING **encPtr; +} INIT_ENCODING; + +int XmlParseXmlDecl(int isGeneralTextEntity, + const ENCODING *enc, + const char *ptr, + const char *end, + const char **badPtr, + const char **versionPtr, + const char **versionEndPtr, + const char **encodingNamePtr, + const ENCODING **namedEncodingPtr, + int *standalonePtr); + +int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); +const ENCODING *XmlGetUtf8InternalEncoding(void); +const ENCODING *XmlGetUtf16InternalEncoding(void); +int FASTCALL XmlUtf8Encode(int charNumber, char *buf); +int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf); +int XmlSizeOfUnknownEncoding(void); + +typedef int (*CONVERTER)(void *userData, const char *p); + +ENCODING * +XmlInitUnknownEncoding(void *mem, + int *table, + CONVERTER convert, + void *userData); + +int XmlParseXmlDeclNS(int isGeneralTextEntity, + const ENCODING *enc, + const char *ptr, + const char *end, + const char **badPtr, + const char **versionPtr, + const char **versionEndPtr, + const char **encodingNamePtr, + const ENCODING **namedEncodingPtr, + int *standalonePtr); + +int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name); +const ENCODING *XmlGetUtf8InternalEncodingNS(void); +const ENCODING *XmlGetUtf16InternalEncodingNS(void); +ENCODING * +XmlInitUnknownEncodingNS(void *mem, + int *table, + CONVERTER convert, + void *userData); +#ifdef __cplusplus +} +#endif + +#endif /* not XmlTok_INCLUDED */ diff --git a/macosx/expat/xmltok_impl.c b/macosx/expat/xmltok_impl.c new file mode 100644 index 0000000..84a3267 --- /dev/null +++ b/macosx/expat/xmltok_impl.c @@ -0,0 +1,1779 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef IS_INVALID_CHAR +#define IS_INVALID_CHAR(enc, ptr, n) (0) +#endif + +#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_INVALID_CHAR(enc, ptr, n)) { \ + *(nextTokPtr) = (ptr); \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +#define INVALID_CASES(ptr, nextTokPtr) \ + INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ + case BT_NONXML: \ + case BT_MALFORM: \ + case BT_TRAIL: \ + *(nextTokPtr) = (ptr); \ + return XML_TOK_INVALID; + +#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (!IS_NAME_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + case BT_NMSTRT: \ + case BT_HEX: \ + case BT_DIGIT: \ + case BT_NAME: \ + case BT_MINUS: \ + ptr += MINBPC(enc); \ + break; \ + CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) + +#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + case BT_NMSTRT: \ + case BT_HEX: \ + ptr += MINBPC(enc); \ + break; \ + CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) + +#ifndef PREFIX +#define PREFIX(ident) ident +#endif + +/* ptr points to character following " */ + switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { + case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + /* fall through */ + case BT_S: case BT_CR: case BT_LF: + *nextTokPtr = ptr; + return XML_TOK_DECL_OPEN; + case BT_NMSTRT: + case BT_HEX: + ptr += MINBPC(enc); + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, + const char *end, int *tokPtr) +{ + int upper = 0; + *tokPtr = XML_TOK_PI; + if (end - ptr != MINBPC(enc)*3) + return 1; + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_x: + break; + case ASCII_X: + upper = 1; + break; + default: + return 1; + } + ptr += MINBPC(enc); + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_m: + break; + case ASCII_M: + upper = 1; + break; + default: + return 1; + } + ptr += MINBPC(enc); + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_l: + break; + case ASCII_L: + upper = 1; + break; + default: + return 1; + } + if (upper) + return 0; + *tokPtr = XML_TOK_XML_DECL; + return 1; +} + +/* ptr points to character following " 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_RSQB: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) + break; + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr -= MINBPC(enc); + break; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CDATA_SECT_CLOSE; + case BT_CR: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + case BT_LF: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + INVALID_CASES(ptr, nextTokPtr) + default: + ptr += MINBPC(enc); + break; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NONXML: + case BT_MALFORM: + case BT_TRAIL: + case BT_CR: + case BT_LF: + case BT_RSQB: + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following " 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_LT: + return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_AMP: + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_CR: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + case BT_LF: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + case BT_RSQB: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_RSQB; + if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) + break; + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_RSQB; + if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr -= MINBPC(enc); + break; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + INVALID_CASES(ptr, nextTokPtr) + default: + ptr += MINBPC(enc); + break; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_RSQB: + if (ptr + MINBPC(enc) != end) { + if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { + ptr += MINBPC(enc); + break; + } + if (ptr + 2*MINBPC(enc) != end) { + if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) { + ptr += MINBPC(enc); + break; + } + *nextTokPtr = ptr + 2*MINBPC(enc); + return XML_TOK_INVALID; + } + } + /* fall through */ + case BT_AMP: + case BT_LT: + case BT_NONXML: + case BT_MALFORM: + case BT_TRAIL: + case BT_CR: + case BT_LF: + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following "%" */ + +static int PTRCALL +PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: + *nextTokPtr = ptr; + return XML_TOK_PERCENT; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_SEMI: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_PARAM_ENTITY_REF; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_CR: case BT_LF: case BT_S: + case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: + *nextTokPtr = ptr; + return XML_TOK_POUND_NAME; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -XML_TOK_POUND_NAME; +} + +static int PTRCALL +PREFIX(scanLit)(int open, const ENCODING *enc, + const char *ptr, const char *end, + const char **nextTokPtr) +{ + while (ptr != end) { + int t = BYTE_TYPE(enc, ptr); + switch (t) { + INVALID_CASES(ptr, nextTokPtr) + case BT_QUOT: + case BT_APOS: + ptr += MINBPC(enc); + if (t != open) + break; + if (ptr == end) + return -XML_TOK_LITERAL; + *nextTokPtr = ptr; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: case BT_CR: case BT_LF: + case BT_GT: case BT_PERCNT: case BT_LSQB: + return XML_TOK_LITERAL; + default: + return XML_TOK_INVALID; + } + default: + ptr += MINBPC(enc); + break; + } + } + return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + int tok; + if (ptr == end) + return XML_TOK_NONE; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_QUOT: + return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_APOS: + return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_LT: + { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_EXCL: + return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_QUEST: + return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_NMSTRT: + case BT_HEX: + case BT_NONASCII: + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + *nextTokPtr = ptr - MINBPC(enc); + return XML_TOK_INSTANCE_START; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + case BT_CR: + if (ptr + MINBPC(enc) == end) { + *nextTokPtr = end; + /* indicate that this might be part of a CR/LF pair */ + return -XML_TOK_PROLOG_S; + } + /* fall through */ + case BT_S: case BT_LF: + for (;;) { + ptr += MINBPC(enc); + if (ptr == end) + break; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: case BT_LF: + break; + case BT_CR: + /* don't split CR/LF pair */ + if (ptr + MINBPC(enc) != end) + break; + /* fall through */ + default: + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + } + } + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + case BT_PERCNT: + return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_COMMA: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_COMMA; + case BT_LSQB: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OPEN_BRACKET; + case BT_RSQB: + ptr += MINBPC(enc); + if (ptr == end) + return -XML_TOK_CLOSE_BRACKET; + if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { + if (ptr + MINBPC(enc) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { + *nextTokPtr = ptr + 2*MINBPC(enc); + return XML_TOK_COND_SECT_CLOSE; + } + } + *nextTokPtr = ptr; + return XML_TOK_CLOSE_BRACKET; + case BT_LPAR: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OPEN_PAREN; + case BT_RPAR: + ptr += MINBPC(enc); + if (ptr == end) + return -XML_TOK_CLOSE_PAREN; + switch (BYTE_TYPE(enc, ptr)) { + case BT_AST: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_ASTERISK; + case BT_QUEST: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_QUESTION; + case BT_PLUS: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_PLUS; + case BT_CR: case BT_LF: case BT_S: + case BT_GT: case BT_COMMA: case BT_VERBAR: + case BT_RPAR: + *nextTokPtr = ptr; + return XML_TOK_CLOSE_PAREN; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_VERBAR: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OR; + case BT_GT: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DECL_CLOSE; + case BT_NUM: + return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NAME; \ + break; \ + } \ + if (IS_NAME_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NMTOKEN; \ + break; \ + } \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NMSTRT: + case BT_HEX: + tok = XML_TOK_NAME; + ptr += MINBPC(enc); + break; + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: +#ifdef XML_NS + case BT_COLON: +#endif + tok = XML_TOK_NMTOKEN; + ptr += MINBPC(enc); + break; + case BT_NONASCII: + if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { + ptr += MINBPC(enc); + tok = XML_TOK_NAME; + break; + } + if (IS_NAME_CHAR_MINBPC(enc, ptr)) { + ptr += MINBPC(enc); + tok = XML_TOK_NMTOKEN; + break; + } + /* fall through */ + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_GT: case BT_RPAR: case BT_COMMA: + case BT_VERBAR: case BT_LSQB: case BT_PERCNT: + case BT_S: case BT_CR: case BT_LF: + *nextTokPtr = ptr; + return tok; +#ifdef XML_NS + case BT_COLON: + ptr += MINBPC(enc); + switch (tok) { + case XML_TOK_NAME: + if (ptr == end) + return XML_TOK_PARTIAL; + tok = XML_TOK_PREFIXED_NAME; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + default: + tok = XML_TOK_NMTOKEN; + break; + } + break; + case XML_TOK_PREFIXED_NAME: + tok = XML_TOK_NMTOKEN; + break; + } + break; +#endif + case BT_PLUS: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_PLUS; + case BT_AST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_ASTERISK; + case BT_QUEST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_QUESTION; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -tok; +} + +static int PTRCALL +PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, + const char *end, const char **nextTokPtr) +{ + const char *start; + if (ptr == end) + return XML_TOK_NONE; + start = ptr; + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: ptr += n; break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_AMP: + if (ptr == start) + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_LT: + /* this is for inside entity references */ + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_LF: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_CR: + if (ptr == start) { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_S: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_ATTRIBUTE_VALUE_S; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +static int PTRCALL +PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, + const char *end, const char **nextTokPtr) +{ + const char *start; + if (ptr == end) + return XML_TOK_NONE; + start = ptr; + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: ptr += n; break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_AMP: + if (ptr == start) + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_PERCNT: + if (ptr == start) { + int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc), + end, nextTokPtr); + return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_LF: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_CR: + if (ptr == start) { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +#ifdef XML_DTD + +static int PTRCALL +PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, + const char *end, const char **nextTokPtr) +{ + int level = 0; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + end = ptr + n; + } + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + INVALID_CASES(ptr, nextTokPtr) + case BT_LT: + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { + ++level; + ptr += MINBPC(enc); + } + } + break; + case BT_RSQB: + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr += MINBPC(enc); + if (level == 0) { + *nextTokPtr = ptr; + return XML_TOK_IGNORE_SECT; + } + --level; + } + } + break; + default: + ptr += MINBPC(enc); + break; + } + } + return XML_TOK_PARTIAL; +} + +#endif /* XML_DTD */ + +static int PTRCALL +PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, + const char **badPtr) +{ + ptr += MINBPC(enc); + end -= MINBPC(enc); + for (; ptr != end; ptr += MINBPC(enc)) { + switch (BYTE_TYPE(enc, ptr)) { + case BT_DIGIT: + case BT_HEX: + case BT_MINUS: + case BT_APOS: + case BT_LPAR: + case BT_RPAR: + case BT_PLUS: + case BT_COMMA: + case BT_SOL: + case BT_EQUALS: + case BT_QUEST: + case BT_CR: + case BT_LF: + case BT_SEMI: + case BT_EXCL: + case BT_AST: + case BT_PERCNT: + case BT_NUM: +#ifdef XML_NS + case BT_COLON: +#endif + break; + case BT_S: + if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { + *badPtr = ptr; + return 0; + } + break; + case BT_NAME: + case BT_NMSTRT: + if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) + break; + default: + switch (BYTE_TO_ASCII(enc, ptr)) { + case 0x24: /* $ */ + case 0x40: /* @ */ + break; + default: + *badPtr = ptr; + return 0; + } + break; + } + } + return 1; +} + +/* This must only be called for a well-formed start-tag or empty + element tag. Returns the number of attributes. Pointers to the + first attsMax attributes are stored in atts. +*/ + +static int PTRCALL +PREFIX(getAtts)(const ENCODING *enc, const char *ptr, + int attsMax, ATTRIBUTE *atts) +{ + enum { other, inName, inValue } state = inName; + int nAtts = 0; + int open = 0; /* defined when state == inValue; + initialization just to shut up compilers */ + + for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { + switch (BYTE_TYPE(enc, ptr)) { +#define START_NAME \ + if (state == other) { \ + if (nAtts < attsMax) { \ + atts[nAtts].name = ptr; \ + atts[nAtts].normalized = 1; \ + } \ + state = inName; \ + } +#define LEAD_CASE(n) \ + case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NONASCII: + case BT_NMSTRT: + case BT_HEX: + START_NAME + break; +#undef START_NAME + case BT_QUOT: + if (state != inValue) { + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); + state = inValue; + open = BT_QUOT; + } + else if (open == BT_QUOT) { + state = other; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; + } + break; + case BT_APOS: + if (state != inValue) { + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); + state = inValue; + open = BT_APOS; + } + else if (open == BT_APOS) { + state = other; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; + } + break; + case BT_AMP: + if (nAtts < attsMax) + atts[nAtts].normalized = 0; + break; + case BT_S: + if (state == inName) + state = other; + else if (state == inValue + && nAtts < attsMax + && atts[nAtts].normalized + && (ptr == atts[nAtts].valuePtr + || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE + || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE + || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) + atts[nAtts].normalized = 0; + break; + case BT_CR: case BT_LF: + /* This case ensures that the first attribute name is counted + Apart from that we could just change state on the quote. */ + if (state == inName) + state = other; + else if (state == inValue && nAtts < attsMax) + atts[nAtts].normalized = 0; + break; + case BT_GT: + case BT_SOL: + if (state != inValue) + return nAtts; + break; + default: + break; + } + } + /* not reached */ +} + +static int PTRFASTCALL +PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) +{ + int result = 0; + /* skip &# */ + ptr += 2*MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_x)) { + for (ptr += MINBPC(enc); + !CHAR_MATCHES(enc, ptr, ASCII_SEMI); + ptr += MINBPC(enc)) { + int c = BYTE_TO_ASCII(enc, ptr); + switch (c) { + case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: + case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: + result <<= 4; + result |= (c - ASCII_0); + break; + case ASCII_A: case ASCII_B: case ASCII_C: + case ASCII_D: case ASCII_E: case ASCII_F: + result <<= 4; + result += 10 + (c - ASCII_A); + break; + case ASCII_a: case ASCII_b: case ASCII_c: + case ASCII_d: case ASCII_e: case ASCII_f: + result <<= 4; + result += 10 + (c - ASCII_a); + break; + } + if (result >= 0x110000) + return -1; + } + } + else { + for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { + int c = BYTE_TO_ASCII(enc, ptr); + result *= 10; + result += (c - ASCII_0); + if (result >= 0x110000) + return -1; + } + } + return checkCharRefNumber(result); +} + +static int PTRCALL +PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, + const char *end) +{ + switch ((end - ptr)/MINBPC(enc)) { + case 2: + if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_l: + return ASCII_LT; + case ASCII_g: + return ASCII_GT; + } + } + break; + case 3: + if (CHAR_MATCHES(enc, ptr, ASCII_a)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_m)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) + return ASCII_AMP; + } + } + break; + case 4: + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_q: + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_u)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_t)) + return ASCII_QUOT; + } + } + break; + case ASCII_a: + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_s)) + return ASCII_APOS; + } + } + break; + } + } + return 0; +} + +static int PTRCALL +PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) +{ + for (;;) { + switch (BYTE_TYPE(enc, ptr1)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (*ptr1++ != *ptr2++) \ + return 0; + LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2) +#undef LEAD_CASE + /* fall through */ + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_NONASCII: + case BT_NMSTRT: +#ifdef XML_NS + case BT_COLON: +#endif + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + if (*ptr2++ != *ptr1++) + return 0; + if (MINBPC(enc) > 1) { + if (*ptr2++ != *ptr1++) + return 0; + if (MINBPC(enc) > 2) { + if (*ptr2++ != *ptr1++) + return 0; + if (MINBPC(enc) > 3) { + if (*ptr2++ != *ptr1++) + return 0; + } + } + } + break; + default: + if (MINBPC(enc) == 1 && *ptr1 == *ptr2) + return 1; + switch (BYTE_TYPE(enc, ptr2)) { + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + case BT_NONASCII: + case BT_NMSTRT: +#ifdef XML_NS + case BT_COLON: +#endif + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + return 0; + default: + return 1; + } + } + } + /* not reached */ +} + +static int PTRCALL +PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, + const char *end1, const char *ptr2) +{ + for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { + if (ptr1 == end1) + return 0; + if (!CHAR_MATCHES(enc, ptr1, *ptr2)) + return 0; + } + return ptr1 == end1; +} + +static int PTRFASTCALL +PREFIX(nameLength)(const ENCODING *enc, const char *ptr) +{ + const char *start = ptr; + for (;;) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: ptr += n; break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NONASCII: + case BT_NMSTRT: +#ifdef XML_NS + case BT_COLON: +#endif + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + ptr += MINBPC(enc); + break; + default: + return ptr - start; + } + } +} + +static const char * PTRFASTCALL +PREFIX(skipS)(const ENCODING *enc, const char *ptr) +{ + for (;;) { + switch (BYTE_TYPE(enc, ptr)) { + case BT_LF: + case BT_CR: + case BT_S: + ptr += MINBPC(enc); + break; + default: + return ptr; + } + } +} + +static void PTRCALL +PREFIX(updatePosition)(const ENCODING *enc, + const char *ptr, + const char *end, + POSITION *pos) +{ + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + ptr += n; \ + break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_LF: + pos->columnNumber = (unsigned)-1; + pos->lineNumber++; + ptr += MINBPC(enc); + break; + case BT_CR: + pos->lineNumber++; + ptr += MINBPC(enc); + if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + pos->columnNumber = (unsigned)-1; + break; + default: + ptr += MINBPC(enc); + break; + } + pos->columnNumber++; + } +} + +#undef DO_LEAD_CASE +#undef MULTIBYTE_CASES +#undef INVALID_CASES +#undef CHECK_NAME_CASE +#undef CHECK_NAME_CASES +#undef CHECK_NMSTRT_CASE +#undef CHECK_NMSTRT_CASES + diff --git a/macosx/expat/xmltok_impl.h b/macosx/expat/xmltok_impl.h new file mode 100644 index 0000000..da0ea60 --- /dev/null +++ b/macosx/expat/xmltok_impl.h @@ -0,0 +1,46 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file COPYING for copying permission. +*/ + +enum { + BT_NONXML, + BT_MALFORM, + BT_LT, + BT_AMP, + BT_RSQB, + BT_LEAD2, + BT_LEAD3, + BT_LEAD4, + BT_TRAIL, + BT_CR, + BT_LF, + BT_GT, + BT_QUOT, + BT_APOS, + BT_EQUALS, + BT_QUEST, + BT_EXCL, + BT_SOL, + BT_SEMI, + BT_NUM, + BT_LSQB, + BT_S, + BT_NMSTRT, + BT_COLON, + BT_HEX, + BT_DIGIT, + BT_NAME, + BT_MINUS, + BT_OTHER, /* known not to be a name or name start character */ + BT_NONASCII, /* might be a name or name start character */ + BT_PERCNT, + BT_LPAR, + BT_RPAR, + BT_AST, + BT_PLUS, + BT_COMMA, + BT_VERBAR +}; + +#include diff --git a/macosx/expat/xmltok_ns.c b/macosx/expat/xmltok_ns.c new file mode 100644 index 0000000..5610eb9 --- /dev/null +++ b/macosx/expat/xmltok_ns.c @@ -0,0 +1,106 @@ +const ENCODING * +NS(XmlGetUtf8InternalEncoding)(void) +{ + return &ns(internal_utf8_encoding).enc; +} + +const ENCODING * +NS(XmlGetUtf16InternalEncoding)(void) +{ +#if BYTEORDER == 1234 + return &ns(internal_little2_encoding).enc; +#elif BYTEORDER == 4321 + return &ns(internal_big2_encoding).enc; +#else + const short n = 1; + return (*(const char *)&n + ? &ns(internal_little2_encoding).enc + : &ns(internal_big2_encoding).enc); +#endif +} + +static const ENCODING *NS(encodings)[] = { + &ns(latin1_encoding).enc, + &ns(ascii_encoding).enc, + &ns(utf8_encoding).enc, + &ns(big2_encoding).enc, + &ns(big2_encoding).enc, + &ns(little2_encoding).enc, + &ns(utf8_encoding).enc /* NO_ENC */ +}; + +static int PTRCALL +NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + return initScan(NS(encodings), (const INIT_ENCODING *)enc, + XML_PROLOG_STATE, ptr, end, nextTokPtr); +} + +static int PTRCALL +NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + return initScan(NS(encodings), (const INIT_ENCODING *)enc, + XML_CONTENT_STATE, ptr, end, nextTokPtr); +} + +int +NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, + const char *name) +{ + int i = getEncodingIndex(name); + if (i == UNKNOWN_ENC) + return 0; + SET_INIT_ENC_INDEX(p, i); + p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); + p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); + p->initEnc.updatePosition = initUpdatePosition; + p->encPtr = encPtr; + *encPtr = &(p->initEnc); + return 1; +} + +static const ENCODING * +NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) +{ +#define ENCODING_MAX 128 + char buf[ENCODING_MAX]; + char *p = buf; + int i; + XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); + if (ptr != end) + return 0; + *p = 0; + if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) + return enc; + i = getEncodingIndex(buf); + if (i == UNKNOWN_ENC) + return 0; + return NS(encodings)[i]; +} + +int +NS(XmlParseXmlDecl)(int isGeneralTextEntity, + const ENCODING *enc, + const char *ptr, + const char *end, + const char **badPtr, + const char **versionPtr, + const char **versionEndPtr, + const char **encodingName, + const ENCODING **encoding, + int *standalone) +{ + return doParseXmlDecl(NS(findEncoding), + isGeneralTextEntity, + enc, + ptr, + end, + badPtr, + versionPtr, + versionEndPtr, + encodingName, + encoding, + standalone); +} diff --git a/macosx/libwbxml.xcode/project.pbxproj b/macosx/libwbxml.xcode/project.pbxproj new file mode 100644 index 0000000..dfc4166 --- /dev/null +++ b/macosx/libwbxml.xcode/project.pbxproj @@ -0,0 +1,1032 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 39; + objects = { + E0042ADB0A5D09C800DB9445 = { + children = ( + E0042B0D0A5D0A7A00DB9445, + E0042B030A5D0A5700DB9445, + E0A01F9F0A625C5000514B02, + E0042AEC0A5D09D400DB9445, + ); + isa = PBXGroup; + refType = 4; + sourceTree = ""; + }; + E0042ADD0A5D09C800DB9445 = { + buildSettings = { + }; + buildStyles = ( + E0BEC8A90A5EB1DF000A0E1D, + E0BEC8AA0A5EB1DF000A0E1D, + ); + hasScannedForEncodings = 0; + isa = PBXProject; + mainGroup = E0042ADB0A5D09C800DB9445; + productRefGroup = E0042AEC0A5D09D400DB9445; + projectDirPath = ""; + targets = ( + E0042AEA0A5D09D400DB9445, + E0042C870A5D102F00DB9445, + E0D8861A0B6E1061007C9014, + E0D886360B6E10DD007C9014, + ); + }; + E0042AE70A5D09D400DB9445 = { + buildActionMask = 2147483647; + files = ( + E0042B310A5D0A7A00DB9445, + E0042B330A5D0A7A00DB9445, + E0042B350A5D0A7A00DB9445, + E0042B370A5D0A7A00DB9445, + E0042B390A5D0A7A00DB9445, + E0042B3B0A5D0A7A00DB9445, + E0042B3D0A5D0A7A00DB9445, + E0042B3F0A5D0A7A00DB9445, + E0042B400A5D0A7A00DB9445, + E0042B420A5D0A7A00DB9445, + E0042B440A5D0A7A00DB9445, + E0042B460A5D0A7A00DB9445, + E0042B480A5D0A7A00DB9445, + E0042B4A0A5D0A7A00DB9445, + E0042B4C0A5D0A7A00DB9445, + E0042B4E0A5D0A7A00DB9445, + E0042B500A5D0A7A00DB9445, + E0042B520A5D0A7A00DB9445, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E0042AE80A5D09D400DB9445 = { + buildActionMask = 2147483647; + files = ( + E0042B320A5D0A7A00DB9445, + E0042B340A5D0A7A00DB9445, + E0042B360A5D0A7A00DB9445, + E0042B380A5D0A7A00DB9445, + E0042B3A0A5D0A7A00DB9445, + E0042B3C0A5D0A7A00DB9445, + E0042B3E0A5D0A7A00DB9445, + E0042B410A5D0A7A00DB9445, + E0042B430A5D0A7A00DB9445, + E0042B450A5D0A7A00DB9445, + E0042B470A5D0A7A00DB9445, + E0042B490A5D0A7A00DB9445, + E0042B4B0A5D0A7A00DB9445, + E0042B4D0A5D0A7A00DB9445, + E0042B4F0A5D0A7A00DB9445, + E0042B510A5D0A7A00DB9445, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E0042AE90A5D09D400DB9445 = { + buildActionMask = 2147483647; + files = ( + E0042CCE0A5D13EF00DB9445, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E0042AEA0A5D09D400DB9445 = { + buildPhases = ( + E0042AE70A5D09D400DB9445, + E0042AE80A5D09D400DB9445, + E0042AE90A5D09D400DB9445, + ); + buildRules = ( + ); + buildSettings = { + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = wbxml2; + ZERO_LINK = YES; + }; + dependencies = ( + E0042CCD0A5D13EA00DB9445, + ); + isa = PBXNativeTarget; + name = wbxml2; + productName = wbxml2; + productReference = E0042AEB0A5D09D400DB9445; + productType = "com.apple.product-type.library.static"; + }; + E0042AEB0A5D09D400DB9445 = { + explicitFileType = archive.ar; + includeInIndex = 0; + isa = PBXFileReference; + path = libwbxml2.a; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E0042AEC0A5D09D400DB9445 = { + children = ( + E0042AEB0A5D09D400DB9445, + E0042C880A5D102F00DB9445, + E0D8861B0B6E1061007C9014, + E0D886370B6E10DD007C9014, + ); + isa = PBXGroup; + name = Products; + refType = 4; + sourceTree = ""; + }; + E0042B030A5D0A5700DB9445 = { + children = ( + E0042B040A5D0A5700DB9445, + E0042B050A5D0A5700DB9445, + E0042B070A5D0A5700DB9445, + E0042B080A5D0A5700DB9445, + ); + isa = PBXGroup; + name = tools; + path = ../tools; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + E0042B040A5D0A5700DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = attgetopt.c; + refType = 4; + sourceTree = ""; + }; + E0042B050A5D0A5700DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = getopt.h; + refType = 4; + sourceTree = ""; + }; + E0042B070A5D0A5700DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml2xml_tool.c; + refType = 4; + sourceTree = ""; + }; + E0042B080A5D0A5700DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = xml2wbxml_tool.c; + refType = 4; + sourceTree = ""; + }; + E0042B0D0A5D0A7A00DB9445 = { + children = ( + E0042B0F0A5D0A7A00DB9445, + E0042B100A5D0A7A00DB9445, + E0042B110A5D0A7A00DB9445, + E0042B120A5D0A7A00DB9445, + E0042B130A5D0A7A00DB9445, + E0042B140A5D0A7A00DB9445, + E0042B150A5D0A7A00DB9445, + E0042B160A5D0A7A00DB9445, + E0042B170A5D0A7A00DB9445, + E0042B180A5D0A7A00DB9445, + E0042B190A5D0A7A00DB9445, + E0042B1A0A5D0A7A00DB9445, + E0042B1B0A5D0A7A00DB9445, + E0042B1C0A5D0A7A00DB9445, + E0042B1D0A5D0A7A00DB9445, + E0042B1E0A5D0A7A00DB9445, + E0042B1F0A5D0A7A00DB9445, + E0042B200A5D0A7A00DB9445, + E0042B210A5D0A7A00DB9445, + E0042B220A5D0A7A00DB9445, + E0042B230A5D0A7A00DB9445, + E0042B240A5D0A7A00DB9445, + E0042B250A5D0A7A00DB9445, + E0042B260A5D0A7A00DB9445, + E0042B270A5D0A7A00DB9445, + E0042B280A5D0A7A00DB9445, + E0042B290A5D0A7A00DB9445, + E0042B2A0A5D0A7A00DB9445, + E0042B2B0A5D0A7A00DB9445, + E0042B2C0A5D0A7A00DB9445, + E0042B2D0A5D0A7A00DB9445, + E0042B2E0A5D0A7A00DB9445, + E0042B2F0A5D0A7A00DB9445, + E0042B300A5D0A7A00DB9445, + ); + isa = PBXGroup; + name = src; + path = ../src; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + E0042B0F0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml.h; + refType = 4; + sourceTree = ""; + }; + E0042B100A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_base64.c; + refType = 4; + sourceTree = ""; + }; + E0042B110A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_base64.h; + refType = 4; + sourceTree = ""; + }; + E0042B120A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_buffers.c; + refType = 4; + sourceTree = ""; + }; + E0042B130A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_buffers.h; + refType = 4; + sourceTree = ""; + }; + E0042B140A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_charset.c; + refType = 4; + sourceTree = ""; + }; + E0042B150A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_charset.h; + refType = 4; + sourceTree = ""; + }; + E0042B160A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_conv.c; + refType = 4; + sourceTree = ""; + }; + E0042B170A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_conv.h; + refType = 4; + sourceTree = ""; + }; + E0042B180A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_elt.c; + refType = 4; + sourceTree = ""; + }; + E0042B190A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_elt.h; + refType = 4; + sourceTree = ""; + }; + E0042B1A0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_encoder.c; + refType = 4; + sourceTree = ""; + }; + E0042B1B0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_encoder.h; + refType = 4; + sourceTree = ""; + }; + E0042B1C0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_errors.c; + refType = 4; + sourceTree = ""; + }; + E0042B1D0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_errors.h; + refType = 4; + sourceTree = ""; + }; + E0042B1E0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_handlers.h; + refType = 4; + sourceTree = ""; + }; + E0042B1F0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_lists.c; + refType = 4; + sourceTree = ""; + }; + E0042B200A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_lists.h; + refType = 4; + sourceTree = ""; + }; + E0042B210A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_log.c; + refType = 4; + sourceTree = ""; + }; + E0042B220A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_log.h; + refType = 4; + sourceTree = ""; + }; + E0042B230A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_mem.c; + refType = 4; + sourceTree = ""; + }; + E0042B240A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_mem.h; + refType = 4; + sourceTree = ""; + }; + E0042B250A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_parser.c; + refType = 4; + sourceTree = ""; + }; + E0042B260A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_parser.h; + refType = 4; + sourceTree = ""; + }; + E0042B270A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_tables.c; + refType = 4; + sourceTree = ""; + }; + E0042B280A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_tables.h; + refType = 4; + sourceTree = ""; + }; + E0042B290A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_tree.c; + refType = 4; + sourceTree = ""; + }; + E0042B2A0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_tree.h; + refType = 4; + sourceTree = ""; + }; + E0042B2B0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_tree_clb_wbxml.c; + refType = 4; + sourceTree = ""; + }; + E0042B2C0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_tree_clb_wbxml.h; + refType = 4; + sourceTree = ""; + }; + E0042B2D0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_tree_clb_xml.c; + refType = 4; + sourceTree = ""; + }; + E0042B2E0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_tree_clb_xml.h; + refType = 4; + sourceTree = ""; + }; + E0042B2F0A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = wbxml_wrap_syncml.c; + refType = 4; + sourceTree = ""; + }; + E0042B300A5D0A7A00DB9445 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = wbxml_wrap_syncml.h; + refType = 4; + sourceTree = ""; + }; + E0042B310A5D0A7A00DB9445 = { + fileRef = E0042B0F0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B320A5D0A7A00DB9445 = { + fileRef = E0042B100A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B330A5D0A7A00DB9445 = { + fileRef = E0042B110A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B340A5D0A7A00DB9445 = { + fileRef = E0042B120A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B350A5D0A7A00DB9445 = { + fileRef = E0042B130A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B360A5D0A7A00DB9445 = { + fileRef = E0042B140A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B370A5D0A7A00DB9445 = { + fileRef = E0042B150A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B380A5D0A7A00DB9445 = { + fileRef = E0042B160A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B390A5D0A7A00DB9445 = { + fileRef = E0042B170A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B3A0A5D0A7A00DB9445 = { + fileRef = E0042B180A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B3B0A5D0A7A00DB9445 = { + fileRef = E0042B190A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B3C0A5D0A7A00DB9445 = { + fileRef = E0042B1A0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B3D0A5D0A7A00DB9445 = { + fileRef = E0042B1B0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B3E0A5D0A7A00DB9445 = { + fileRef = E0042B1C0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B3F0A5D0A7A00DB9445 = { + fileRef = E0042B1D0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B400A5D0A7A00DB9445 = { + fileRef = E0042B1E0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B410A5D0A7A00DB9445 = { + fileRef = E0042B1F0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B420A5D0A7A00DB9445 = { + fileRef = E0042B200A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B430A5D0A7A00DB9445 = { + fileRef = E0042B210A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B440A5D0A7A00DB9445 = { + fileRef = E0042B220A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B450A5D0A7A00DB9445 = { + fileRef = E0042B230A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B460A5D0A7A00DB9445 = { + fileRef = E0042B240A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B470A5D0A7A00DB9445 = { + fileRef = E0042B250A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B480A5D0A7A00DB9445 = { + fileRef = E0042B260A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B490A5D0A7A00DB9445 = { + fileRef = E0042B270A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B4A0A5D0A7A00DB9445 = { + fileRef = E0042B280A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B4B0A5D0A7A00DB9445 = { + fileRef = E0042B290A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B4C0A5D0A7A00DB9445 = { + fileRef = E0042B2A0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B4D0A5D0A7A00DB9445 = { + fileRef = E0042B2B0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B4E0A5D0A7A00DB9445 = { + fileRef = E0042B2C0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B4F0A5D0A7A00DB9445 = { + fileRef = E0042B2D0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B500A5D0A7A00DB9445 = { + fileRef = E0042B2E0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B510A5D0A7A00DB9445 = { + fileRef = E0042B2F0A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042B520A5D0A7A00DB9445 = { + fileRef = E0042B300A5D0A7A00DB9445; + isa = PBXBuildFile; + }; + E0042C840A5D102F00DB9445 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E0042C850A5D102F00DB9445 = { + buildActionMask = 2147483647; + files = ( + E0A01FBB0A625C5000514B02, + E0A01FBD0A625C5000514B02, + E0A01FC60A625C8700514B02, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E0042C860A5D102F00DB9445 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E0042C870A5D102F00DB9445 = { + buildPhases = ( + E0042C840A5D102F00DB9445, + E0042C850A5D102F00DB9445, + E0042C860A5D102F00DB9445, + ); + buildRules = ( + ); + buildSettings = { + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = expat; + ZERO_LINK = YES; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = expat; + productName = expat; + productReference = E0042C880A5D102F00DB9445; + productType = "com.apple.product-type.library.static"; + }; + E0042C880A5D102F00DB9445 = { + explicitFileType = archive.ar; + includeInIndex = 0; + isa = PBXFileReference; + path = libexpat.a; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E0042CCC0A5D13EA00DB9445 = { + containerPortal = E0042ADD0A5D09C800DB9445; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = E0042C870A5D102F00DB9445; + remoteInfo = expat; + }; + E0042CCD0A5D13EA00DB9445 = { + isa = PBXTargetDependency; + target = E0042C870A5D102F00DB9445; + targetProxy = E0042CCC0A5D13EA00DB9445; + }; + E0042CCE0A5D13EF00DB9445 = { + fileRef = E0042C880A5D102F00DB9445; + isa = PBXBuildFile; + }; + E0A01F9F0A625C5000514B02 = { + children = ( + E0A01FA00A625C5000514B02, + E0A01FA10A625C5000514B02, + E0A01FA20A625C5000514B02, + E0A01FA30A625C5000514B02, + E0A01FA40A625C5000514B02, + E0A01FA50A625C5000514B02, + E0A01FA60A625C5000514B02, + E0A01FA70A625C5000514B02, + E0A01FA80A625C5000514B02, + E0A01FA90A625C5000514B02, + E0A01FAA0A625C5000514B02, + E0A01FAB0A625C5000514B02, + E0A01FAC0A625C5000514B02, + E0A01FAD0A625C5000514B02, + E0A01FAE0A625C5000514B02, + E0A01FAF0A625C5000514B02, + E0A01FB00A625C5000514B02, + ); + isa = PBXGroup; + path = expat; + refType = 4; + sourceTree = ""; + }; + E0A01FA00A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ascii.h; + refType = 4; + sourceTree = ""; + }; + E0A01FA10A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = asciitab.h; + refType = 4; + sourceTree = ""; + }; + E0A01FA20A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = expat.h; + refType = 4; + sourceTree = ""; + }; + E0A01FA30A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = expat_config.h; + refType = 4; + sourceTree = ""; + }; + E0A01FA40A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = iasciitab.h; + refType = 4; + sourceTree = ""; + }; + E0A01FA50A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = internal.h; + refType = 4; + sourceTree = ""; + }; + E0A01FA60A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = latin1tab.h; + refType = 4; + sourceTree = ""; + }; + E0A01FA70A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = nametab.h; + refType = 4; + sourceTree = ""; + }; + E0A01FA80A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = utf8tab.h; + refType = 4; + sourceTree = ""; + }; + E0A01FA90A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = xmlparse.c; + refType = 4; + sourceTree = ""; + }; + E0A01FAA0A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = xmlrole.c; + refType = 4; + sourceTree = ""; + }; + E0A01FAB0A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = xmlrole.h; + refType = 4; + sourceTree = ""; + }; + E0A01FAC0A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = xmltok.c; + refType = 4; + sourceTree = ""; + }; + E0A01FAD0A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = xmltok.h; + refType = 4; + sourceTree = ""; + }; + E0A01FAE0A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = xmltok_impl.c; + refType = 4; + sourceTree = ""; + }; + E0A01FAF0A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = xmltok_impl.h; + refType = 4; + sourceTree = ""; + }; + E0A01FB00A625C5000514B02 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = xmltok_ns.c; + refType = 4; + sourceTree = ""; + }; + E0A01FBB0A625C5000514B02 = { + fileRef = E0A01FAA0A625C5000514B02; + isa = PBXBuildFile; + }; + E0A01FBD0A625C5000514B02 = { + fileRef = E0A01FAC0A625C5000514B02; + isa = PBXBuildFile; + }; + E0A01FC60A625C8700514B02 = { + fileRef = E0A01FA90A625C5000514B02; + isa = PBXBuildFile; + }; + E0BEC8A90A5EB1DF000A0E1D = { + buildSettings = { + COPY_PHASE_STRIP = NO; + }; + isa = PBXBuildStyle; + name = Development; + }; + E0BEC8AA0A5EB1DF000A0E1D = { + buildSettings = { + COPY_PHASE_STRIP = YES; + }; + isa = PBXBuildStyle; + name = Deployment; + }; + E0D886180B6E1061007C9014 = { + buildActionMask = 2147483647; + files = ( + E0D8861D0B6E106F007C9014, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E0D886190B6E1061007C9014 = { + buildActionMask = 2147483647; + files = ( + E0D8861E0B6E1074007C9014, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E0D8861A0B6E1061007C9014 = { + buildPhases = ( + E0D886180B6E1061007C9014, + E0D886190B6E1061007C9014, + ); + buildRules = ( + ); + buildSettings = { + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = "$(HOME)/bin"; + PREBINDING = NO; + PRODUCT_NAME = wbxml2xml; + ZERO_LINK = YES; + }; + dependencies = ( + E0D886420B6E1124007C9014, + ); + isa = PBXNativeTarget; + name = wbxml2xml; + productName = Pouet; + productReference = E0D8861B0B6E1061007C9014; + productType = "com.apple.product-type.tool"; + }; + E0D8861B0B6E1061007C9014 = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = wbxml2xml; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E0D8861D0B6E106F007C9014 = { + fileRef = E0042B070A5D0A5700DB9445; + isa = PBXBuildFile; + }; + E0D8861E0B6E1074007C9014 = { + fileRef = E0042AEB0A5D09D400DB9445; + isa = PBXBuildFile; + }; + E0D886340B6E10DD007C9014 = { + buildActionMask = 2147483647; + files = ( + E0D886390B6E10E9007C9014, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E0D886350B6E10DD007C9014 = { + buildActionMask = 2147483647; + files = ( + E0D8863A0B6E10EF007C9014, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E0D886360B6E10DD007C9014 = { + buildPhases = ( + E0D886340B6E10DD007C9014, + E0D886350B6E10DD007C9014, + ); + buildRules = ( + ); + buildSettings = { + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = "$(HOME)/bin"; + PREBINDING = NO; + PRODUCT_NAME = xml2wbxml; + ZERO_LINK = YES; + }; + dependencies = ( + E0D886440B6E1127007C9014, + ); + isa = PBXNativeTarget; + name = xml2wbxml; + productName = xml2wbxml; + productReference = E0D886370B6E10DD007C9014; + productType = "com.apple.product-type.tool"; + }; + E0D886370B6E10DD007C9014 = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = xml2wbxml; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E0D886390B6E10E9007C9014 = { + fileRef = E0042B080A5D0A5700DB9445; + isa = PBXBuildFile; + }; + E0D8863A0B6E10EF007C9014 = { + fileRef = E0042AEB0A5D09D400DB9445; + isa = PBXBuildFile; + }; + E0D886410B6E1124007C9014 = { + containerPortal = E0042ADD0A5D09C800DB9445; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = E0042AEA0A5D09D400DB9445; + remoteInfo = wbxml2; + }; + E0D886420B6E1124007C9014 = { + isa = PBXTargetDependency; + target = E0042AEA0A5D09D400DB9445; + targetProxy = E0D886410B6E1124007C9014; + }; + E0D886430B6E1127007C9014 = { + containerPortal = E0042ADD0A5D09C800DB9445; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = E0042AEA0A5D09D400DB9445; + remoteInfo = wbxml2; + }; + E0D886440B6E1127007C9014 = { + isa = PBXTargetDependency; + target = E0042AEA0A5D09D400DB9445; + targetProxy = E0D886430B6E1127007C9014; + }; + }; + rootObject = E0042ADD0A5D09C800DB9445; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..3a25bb8 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,43 @@ +LINK_DIRECTORIES( ${EXPAT_LIBRARY_DIRS} ) + +INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${EXPAT_INCLUDE_DIRS} ) + +SET( libwbxml_LIB_SRCS + wbxml_base64.c + wbxml_buffers.c + wbxml_charset.c + wbxml_conv.c + wbxml_elt.c + wbxml_encoder.c + wbxml_errors.c + wbxml_lists.c + wbxml_log.c + wbxml_mem.c + wbxml_parser.c + wbxml_tables.c + wbxml_tree.c + wbxml_tree_clb_wbxml.c + wbxml_tree_clb_xml.c +) + +ADD_LIBRARY( wbxml2 SHARED ${libwbxml_LIB_SRCS} ) + +SET_TARGET_PROPERTIES( wbxml2 PROPERTIES SOVERSION ${LIBWBXML_LIBVERSION_SOVERSION} ) +SET_TARGET_PROPERTIES( wbxml2 PROPERTIES VERSION ${LIBWBXML_LIBVERSION_VERSION} ) +TARGET_LINK_LIBRARIES( wbxml2 ${EXPAT_LIBRARIES} ) + +INSTALL( TARGETS wbxml2 + RUNTIME DESTINATION ${LIBWBXML_BIN_DIR} + LIBRARY DESTINATION ${LIBWBXML_LIBRARIES_DIR} + ARCHIVE DESTINATION ${LIBWBXML_LIBRARIES_DIR} +) + +INSTALL( FILES + wbxml.h + ${CMAKE_CURRENT_BINARY_DIR}/../wbxml_config.h + wbxml_conv.h + wbxml_defines.h + wbxml_errors.h + DESTINATION ${LIBWBXML_INCLUDE_DIR}/wbxml +) + diff --git a/src/wbxml.h b/src/wbxml.h new file mode 100644 index 0000000..be45eb8 --- /dev/null +++ b/src/wbxml.h @@ -0,0 +1,46 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml.h + * @ingroup wbxml + * + * @author Aymerick Jehanne + * @date 02/11/11 + * + * @brief WBXML Library Main Header + */ + +#ifndef WBXML_H +#define WBXML_H + +#include "wbxml_config.h" +#include "wbxml_defines.h" +#include "wbxml_errors.h" +#include "wbxml_conv.h" + +/** @} */ + +#endif /* WBXML_H */ diff --git a/src/wbxml_base64.c b/src/wbxml_base64.c new file mode 100644 index 0000000..45a2188 --- /dev/null +++ b/src/wbxml_base64.c @@ -0,0 +1,166 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_base64.c + * @ingroup wbxml_base64 + * + * @author Aymerick Jehanne + * @date 01/11/03 + * + * @brief Base64 encoding/decoding functions + * + * @note Code adapted from APR library (http://apr.apache.org/) + */ + +#include "wbxml_base64.h" +#include "wbxml_mem.h" + + +/* aaaack but it's fast and const should make it shared text page. */ +static const unsigned char pr2six[256] = +{ + /* ASCII table */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +}; + +/** Base64 table */ +static const char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + +/********************************** + * Public functions + */ + +/* Function adapted from APR library (http://apr.apache.org/) */ +WBXML_DECLARE(WB_UTINY *) wbxml_base64_encode(const WB_UTINY *buffer, WB_LONG len) +{ + WB_LONG i = 0; + WB_UTINY *p = NULL, *result = NULL; + + if ((buffer == NULL) || (len <= 0)) + return NULL; + + /* Malloc result buffer */ + if ((result = (WB_UTINY *) wbxml_malloc(((len + 2) / 3 * 4) + 1 + 1)) == NULL) + return NULL; + + p = result; + for (i = 0; i < len - 2; i += 3) { + *p++ = basis_64[(buffer[i] >> 2) & 0x3F]; + *p++ = basis_64[((buffer[i] & 0x3) << 4) | + ((int) (buffer[i + 1] & 0xF0) >> 4)]; + *p++ = basis_64[((buffer[i + 1] & 0xF) << 2) | + ((int) (buffer[i + 2] & 0xC0) >> 6)]; + *p++ = basis_64[buffer[i + 2] & 0x3F]; + } + if (i < len) { + *p++ = basis_64[(buffer[i] >> 2) & 0x3F]; + if (i == (len - 1)) { + *p++ = basis_64[((buffer[i] & 0x3) << 4)]; + *p++ = '='; + } + else { + *p++ = basis_64[((buffer[i] & 0x3) << 4) | + ((int) (buffer[i + 1] & 0xF0) >> 4)]; + *p++ = basis_64[((buffer[i + 1] & 0xF) << 2)]; + } + *p++ = '='; + } + + *p++ = '\0'; + + return result; +} + + +/* Function adapted from APR library (http://apr.apache.org/) */ +WBXML_DECLARE(WB_LONG) wbxml_base64_decode(const WB_UTINY *buffer, WB_LONG len, WB_UTINY **result) +{ + WB_LONG nbytesdecoded = 0, nprbytes = 0; + const WB_UTINY *bufin = NULL; + const WB_UTINY *end = (len >= 0) ? (buffer + len) : NULL; + WB_UTINY *bufout = NULL; + + if ((buffer == NULL) || (result == NULL)) + return 0; + + /* Initialize output buffer */ + *result = NULL; + + bufin = buffer; + while (bufin != end && pr2six[*bufin] <= 63) + bufin++; + + nprbytes = bufin - buffer; + + nbytesdecoded = ((nprbytes + 3) / 4) * 3; + + /* Malloc result buffer */ + if ((*result = (WB_UTINY*) wbxml_malloc(nbytesdecoded + 1)) == NULL) + return 0; + + bufout = *result; + bufin = buffer; + + while (nprbytes > 4) + { + *(bufout++) = (WB_UTINY) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); + *(bufout++) = (WB_UTINY) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); + *(bufout++) = (WB_UTINY) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); + bufin += 4; + nprbytes -= 4; + } + + /* Note: (nprbytes == 1) would be an error, so just ingore that case */ + if (nprbytes > 1) { + *(bufout++) = (WB_UTINY) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); + } + if (nprbytes > 2) { + *(bufout++) = (WB_UTINY) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); + } + if (nprbytes > 3) { + *(bufout++) = (WB_UTINY) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); + } + + nbytesdecoded -= (4 - nprbytes) & 3; + + return nbytesdecoded; +} diff --git a/src/wbxml_base64.h b/src/wbxml_base64.h new file mode 100644 index 0000000..82bc4fd --- /dev/null +++ b/src/wbxml_base64.h @@ -0,0 +1,77 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_base64.h + * @ingroup wbxml_base64 + * + * @author Aymerick Jehanne + * @date 01/11/03 + * + * @brief Base64 encoding/decoding functions + * + * @note Code adapted from APR library (http://apr.apache.org/) + */ + +#ifndef WBXML_BASE64_H +#define WBXML_BASE64_H + +#include "wbxml.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_base64 + * @{ + */ + +/** + * @brief Encode a buffer to Base64 + * @param buffer The buffer to encode + * @param len Buffer length + * @return The new base64 encoded Buffer (must be freed by caller), or NULL if not enough memory + */ +WBXML_DECLARE(WB_UTINY *) wbxml_base64_encode(const WB_UTINY *buffer, WB_LONG len); + +/** + * @brief Decode a Base64 encoded buffer + * @param buffer The buffer to decode + * @param len Buffer length. If len is negative, assume buffer is terminated + * by a non-Base64 character (such as NUL). + * @param result Resulting decoded buffer + * @return Length of resulting decoded buffer ('0' if no decoded) + * @note Be aware that if return value is '0', then 'result' param will be NULL, else 'result' param + * has to be freed by caller. + */ +WBXML_DECLARE(WB_LONG) wbxml_base64_decode(const WB_UTINY *buffer, WB_LONG len, WB_UTINY **result); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_BASE64_H */ diff --git a/src/wbxml_buffers.c b/src/wbxml_buffers.c new file mode 100644 index 0000000..c764ad4 --- /dev/null +++ b/src/wbxml_buffers.c @@ -0,0 +1,830 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_buffers.c + * @ingroup wbxml_buffers + * + * @author Aymerick Jehanne + * @date 02/03/12 + * + * @brief Generic Buffers Functions + * + * @note Original idea: Kannel Project (http://www.kannel.org/) + */ + +#include +#include + +#include "wbxml_buffers.h" +#include "wbxml_base64.h" + + +/* Memory management define */ +#define WBXML_BUFFER_SPLIT_BLOCK 20 + +/** + * The Generic Buffer type + */ +struct WBXMLBuffer_s +{ + WB_UTINY *data; /**< The data */ + WB_ULONG len; /**< Length of data in buffer */ + WB_ULONG malloced; /**< Length of buffer */ + WB_BOOL is_static; /**< Is it a static buffer ? */ +}; + + +static WB_BOOL grow_buff(WBXMLBuffer *buffer, WB_ULONG size); +static WB_BOOL insert_data(WBXMLBuffer *buffer, WB_ULONG pos, const WB_UTINY *data, WB_ULONG len); + + + +/********************************** + * Public functions + */ + + +WBXML_DECLARE(WBXMLBuffer *) wbxml_buffer_create_real(const WB_UTINY *data, WB_ULONG len, WB_ULONG malloc_block) +{ + WBXMLBuffer *buffer = NULL; + + buffer = (WBXMLBuffer *) wbxml_malloc(sizeof(WBXMLBuffer)); + if (buffer == NULL) + return NULL; + + buffer->is_static = FALSE; + + if ((len <= 0) || (data == NULL)) { + buffer->malloced = 0; + buffer->len = 0; + buffer->data = NULL; + } + else { + if (len + 1 > malloc_block + 1) + buffer->malloced = len + 1 + malloc_block; + else + buffer->malloced = malloc_block + 1; + + buffer->data = (WB_UTINY *) wbxml_malloc(buffer->malloced * sizeof(WB_UTINY)); + if (buffer->data == NULL) { + wbxml_free(buffer); + return NULL; + } + + buffer->len = len; + memcpy(buffer->data, data, len); + buffer->data[len] = '\0'; + } + + return buffer; +} + + +WBXML_DECLARE(WBXMLBuffer *) wbxml_buffer_sta_create_real(const WB_UTINY *data, WB_ULONG len) +{ + WBXMLBuffer *buffer = NULL; + + buffer = (WBXMLBuffer *) wbxml_malloc(sizeof(WBXMLBuffer)); + if (buffer == NULL) { + return NULL; + } + + buffer->is_static = TRUE; + buffer->data = (WB_UTINY *) data; + buffer->len = len; + + return buffer; +} + + +WBXML_DECLARE(void) wbxml_buffer_destroy(WBXMLBuffer *buffer) +{ + if (buffer != NULL) { + if (!buffer->is_static) { + /* Free dynamic data */ + wbxml_free(buffer->data); + } + + /* Free structure */ + wbxml_free(buffer); + } +} + + +WBXML_DECLARE_NONSTD(void) wbxml_buffer_destroy_item(void *buff) +{ + wbxml_buffer_destroy((WBXMLBuffer *) buff); +} + + +WBXML_DECLARE(WBXMLBuffer *) wbxml_buffer_duplicate(WBXMLBuffer *buff) +{ + WBXMLBuffer *result = NULL; + + if (buff == NULL) + return NULL; + + result = wbxml_buffer_create_real(wbxml_buffer_get_cstr(buff), + wbxml_buffer_len(buff), + wbxml_buffer_len(buff)); + + return result; +} + + +WBXML_DECLARE(WB_ULONG) wbxml_buffer_len(WBXMLBuffer *buffer) +{ + if (buffer == NULL) + return 0; + + return buffer->len; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_get_char(WBXMLBuffer *buffer, WB_ULONG pos, WB_UTINY *result) +{ + if ((buffer == NULL) || (pos >= buffer->len)) + return FALSE; + + *result = buffer->data[pos]; + return TRUE; +} + + +WBXML_DECLARE(void) wbxml_buffer_set_char(WBXMLBuffer *buffer, WB_ULONG pos, WB_UTINY ch) +{ + if ((buffer != NULL) && !buffer->is_static && (pos < buffer->len)) + buffer->data[pos] = ch; +} + + +WBXML_DECLARE(WB_UTINY *) wbxml_buffer_get_cstr(WBXMLBuffer *buffer) +{ + if ((buffer == NULL) || (buffer->len == 0)) + return WBXML_UTINY_NULL_STRING; + + return buffer->data; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_insert(WBXMLBuffer *to, WBXMLBuffer *buffer, WB_ULONG pos) +{ + if ((to != NULL) && (buffer != NULL) && !to->is_static) + return insert_data(to, pos, buffer->data, buffer->len); + + return FALSE; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_insert_cstr(WBXMLBuffer *to, WB_UTINY *str, WB_ULONG pos) +{ + if ((to != NULL) && (str != NULL) && !to->is_static) + return insert_data(to, pos, str, WBXML_STRLEN(str)); + + return FALSE; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_append(WBXMLBuffer *dest, WBXMLBuffer *buff) +{ + if ((dest == NULL) || dest->is_static) + return FALSE; + + if (buff == NULL) + return TRUE; + + return wbxml_buffer_append_data(dest, wbxml_buffer_get_cstr(buff), wbxml_buffer_len(buff)); +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_data_real(WBXMLBuffer *buffer, const WB_UTINY *data, WB_ULONG len) +{ + if ((buffer == NULL) || buffer->is_static) + return FALSE; + + if ((data == NULL) || (len == 0)) + return TRUE; + + return insert_data(buffer, buffer->len, data, len); +} + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_cstr_real(WBXMLBuffer *buffer, const WB_UTINY *data) +{ + if ((buffer == NULL) || buffer->is_static) { + return FALSE; + } + + if (data == NULL) + return TRUE; + + return wbxml_buffer_append_data(buffer, data, WBXML_STRLEN(data)); +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_char(WBXMLBuffer *buffer, WB_UTINY ch) +{ + WB_UTINY c = ch; + + if ((buffer == NULL) || buffer->is_static) + return FALSE; + + return insert_data(buffer, buffer->len, &c, 1); +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_mb_uint_32(WBXMLBuffer *buffer, WB_ULONG value) +{ + /** + * A uintvar is defined to be up to 32 bits large + * so it will fit in 5 octets (to handle continuation bits) + */ + WB_UTINY octets[5]; + WB_LONG i = 0, start = 0; + + if ((buffer == NULL) || buffer->is_static) + return FALSE; + + /** + * Handle last byte separately; it has no continuation bit, + * and must be encoded even if value is 0. + */ + octets[4] = (WB_UTINY) (value & 0x7f); + value >>= 7; + + for (i = 3; value > 0 && i >= 0; i--) { + octets[i] = (WB_UTINY) (0x80 | (value & 0x7f)); + value >>= 7; + } + start = i + 1; + + return wbxml_buffer_append_data(buffer, octets + start, 5 - start); +} + + +WBXML_DECLARE(void) wbxml_buffer_delete(WBXMLBuffer *buffer, WB_ULONG pos, WB_ULONG len) +{ + if ((buffer == NULL) || buffer->is_static) + return; + + if (pos > buffer->len) + pos = buffer->len; + + if (pos + len > buffer->len) + len = buffer->len - pos; + + if (len > 0) { + memmove(buffer->data + pos, buffer->data + pos + len, + buffer->len - pos - len); + + buffer->len -= len; + buffer->data[buffer->len] = '\0'; + } +} + + +WBXML_DECLARE(void) wbxml_buffer_shrink_blanks(WBXMLBuffer *buffer) +{ + WB_ULONG i = 0, j = 0, end = 0; + WB_UTINY ch = 0; + + if ((buffer == NULL) || buffer->is_static) + return; + + end = wbxml_buffer_len(buffer); + + for (i = 0; i < end; i++) + { + if (wbxml_buffer_get_char(buffer, i, &ch) && isspace(ch)) + { + /* Replace space by a whitespace */ + if (ch != ' ') + wbxml_buffer_set_char(buffer, i, ' '); + + /* Remove all following spaces */ + j = i = i + 1; + while (wbxml_buffer_get_char(buffer, j, &ch) && isspace(ch)) + j++; + + if (j - i > 1) + wbxml_buffer_delete(buffer, i, j - i); + } + } +} + + +WBXML_DECLARE(void) wbxml_buffer_strip_blanks(WBXMLBuffer *buffer) +{ + WB_ULONG start = 0, end = 0, len = 0; + WB_UTINY ch = 0; + + if ((buffer == NULL) || buffer->is_static) + return; + + /* Remove whitespaces at beginning of buffer... */ + while (wbxml_buffer_get_char(buffer, start, &ch) && + isspace(ch) && + start <= wbxml_buffer_len(buffer)) + { + start ++; + } + + if (start > 0) + wbxml_buffer_delete(buffer, 0, start); + + /* ... and at the end */ + if ((len = wbxml_buffer_len(buffer)) > 0) { + end = len = len - 1; + while (wbxml_buffer_get_char(buffer, end, &ch) && + isspace(ch)) + { + end--; + } + wbxml_buffer_delete(buffer, end + 1, len - end); + } +} + +WBXML_DECLARE(void) wbxml_buffer_no_spaces(WBXMLBuffer *buffer) +{ + WB_ULONG i = 0, j = 0, end = 0; + WB_UTINY ch = 0; + + if ((buffer == NULL) || buffer->is_static) + return; + + while (i < wbxml_buffer_len(buffer)) + { + if (wbxml_buffer_get_char(buffer, i, &ch) && isspace(ch)) + { + wbxml_buffer_delete(buffer, i, 1); + } else { + i++; + } + } +} + +WBXML_DECLARE(WB_LONG) wbxml_buffer_compare(WBXMLBuffer *buff1, WBXMLBuffer *buff2) +{ + WB_LONG ret = 0, len = 0; + + if ((buff1 == NULL) || (buff2 == NULL)) { + if ((buff1 == NULL) && (buff2 == NULL)) + return 0; + + if (buff1 == NULL) + return -1; + else + return 1; + } + + if (buff1->len < buff2->len) + len = buff1->len; + else + len = buff2->len; + + if (len == 0) + { + if (buff1->len == 0 && buff2->len > 0) + return -1; + if (buff1->len > 0 && buff2->len == 0) + return 1; + return 0; + } + + if ((ret = memcmp(buff1->data, buff2->data, len)) == 0) + { + if (buff1->len < buff2->len) + ret = -1; + else { + if (buff1->len > buff2->len) + ret = 1; + } + } + + return ret; +} + + +WBXML_DECLARE(WB_LONG) wbxml_buffer_compare_cstr(WBXMLBuffer *buff, const WB_TINY *str) +{ + WB_LONG ret = 0, len = 0; + + if ((buff == NULL) || (str == NULL)) { + if ((buff == NULL) && (str == NULL)) + return 0; + + if (buff == NULL) + return -1; + else + return 1; + } + + if (buff->len < WBXML_STRLEN(str)) + len = buff->len; + else + len = WBXML_STRLEN(str); + + if (len == 0) + { + if (buff->len == 0 && WBXML_STRLEN(str) > 0) + return -1; + if (buff->len > 0 && WBXML_STRLEN(str) == 0) + return 1; + return 0; + } + + if ((ret = memcmp(buff->data, str, len)) == 0) + { + if (buff->len < WBXML_STRLEN(str)) + ret = -1; + else { + if (buff->len > WBXML_STRLEN(str)) + ret = 1; + } + } + + return ret; +} + + +WBXML_DECLARE(WBXMLList *) wbxml_buffer_split_words_real(WBXMLBuffer *buff) +{ + WB_UTINY *p = NULL; + WBXMLList *list = NULL; + WBXMLBuffer *word = NULL; + WB_ULONG i = 0, start = 0, end = 0; + + if ((list = wbxml_list_create()) == NULL) + return NULL; + + p = buff->data; + i = 0; + while (TRUE) + { + while (i < buff->len && isspace(*p)) { + ++p; + ++i; + } + start = i; + + while (i < buff->len && !isspace(*p)) { + ++p; + ++i; + } + end = i; + + if (start == end) + break; + + if((word = wbxml_buffer_create(buff->data + start, end - start, WBXML_BUFFER_SPLIT_BLOCK)) == NULL) { + wbxml_list_destroy(list, wbxml_buffer_destroy_item); + return NULL; + } + + wbxml_list_append(list, word); + } + + return list; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_search_char(WBXMLBuffer *to, WB_UTINY ch, WB_ULONG pos, WB_ULONG *result) +{ + WB_UTINY *p = NULL; + + if (to == NULL) + return FALSE; + + if (pos >= to->len) + return FALSE; + + if ((p = (WB_UTINY *) memchr(to->data + pos, ch, to->len - pos)) == NULL) + return FALSE; + + if (result != NULL) + *result = p - to->data; + + return TRUE; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_search(WBXMLBuffer *to, WBXMLBuffer *search, WB_ULONG pos, WB_ULONG *result) +{ + WB_UTINY first = 0; + + if ((to == NULL) || (search == NULL)) + return FALSE; + + if (result != NULL) + *result = 0; + + /* Always "find" an empty string */ + if (search->len == 0) + return TRUE; + + /* Check if 'search' is greater than 'to' */ + if (search->len > to->len) + return FALSE; + + /* We are searching for one char */ + if (search->len == 1) + return wbxml_buffer_search_char(to, search->data[0], pos, result); + + /* For each occurrence of search's first character in to, then check if the rest of needle follows. + * Stop if there are no more occurrences, or if the rest of 'search' can't possibly fit in 'to'. */ + first = search->data[0]; + while ((wbxml_buffer_search_char(to, first, pos, &pos)) && + (to->len - pos >= search->len)) + { + if (memcmp(to->data + pos, search->data, search->len) == 0) { + if (result != NULL) + *result = pos; + return TRUE; + } + pos++; + } + + return FALSE; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_search_cstr(WBXMLBuffer *to, WB_UTINY *search, WB_ULONG pos, WB_ULONG *result) +{ + WB_UTINY first = 0; + + if ((to == NULL) || (search == NULL)) + return FALSE; + + if (result != NULL) + *result = 0; + + /* Always "find" an empty string */ + if (WBXML_STRLEN(search) == 0) + return TRUE; + + /* Check if 'search' is greater than 'to' */ + if (WBXML_STRLEN(search) > to->len) + return FALSE; + + /* We are searching for one char */ + if (WBXML_STRLEN(search) == 1) + return wbxml_buffer_search_char(to, search[0], pos, result); + + /* For each occurrence of search's first character in to, then check if the rest of needle follows. + * Stop if there are no more occurrences, or if the rest of 'search' can't possibly fit in 'to'. */ + first = search[0]; + while ((wbxml_buffer_search_char(to, first, pos, &pos)) && + (to->len - pos >= WBXML_STRLEN(search))) + { + if (memcmp(to->data + pos, search, WBXML_STRLEN(search)) == 0) { + if (result != NULL) + *result = pos; + return TRUE; + } + pos++; + } + + return FALSE; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_contains_only_whitespaces(WBXMLBuffer *buffer) +{ + WB_ULONG i = 0; + + if (buffer == NULL) + return FALSE; + + for (i=0; ilen; i++) { + if (!isspace(*(buffer->data + i))) + return FALSE; + } + + return TRUE; +} + + +WBXML_DECLARE(void) wbxml_buffer_hex_to_binary(WBXMLBuffer *buffer) +{ + WB_UTINY *p = NULL; + WB_ULONG i = 0, len = 0; + + if ((buffer == NULL) || buffer->is_static) + return; + + p = buffer->data; + len = wbxml_buffer_len(buffer); + + /* Convert ascii data to binary values */ + for (i = 0; i < len; i++, p++) { + if (*p >= '0' && *p <= '9') + *p -= '0'; + else if (*p >= 'a' && *p <= 'f') + *p = (WB_UTINY) (*p - 'a' + 10); + else if (*p >= 'A' && *p <= 'F') + *p = (WB_UTINY) (*p - 'A' + 10); + else { + /* Bad Bad ! There should be only digits in the buffer ! */ + *p = 0; + } + } + + /* De-hexing will compress data by factor of 2 */ + len = buffer->len / 2; + + for (i = 0; i < len; i++) + buffer->data[i] = (WB_UTINY) (buffer->data[i * 2] * 16 | buffer->data[i * 2 + 1]); + + buffer->len = len; + buffer->data[len] = '\0'; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_buffer_binary_to_hex(WBXMLBuffer *buffer, WB_BOOL uppercase) +{ + WB_UTINY *hexits = NULL; + WB_LONG i = 0; + + if ((buffer == NULL) || buffer->is_static) + return FALSE; + + if (wbxml_buffer_len(buffer) == 0) + return TRUE; + + hexits = (WB_UTINY *)(uppercase ? "0123456789ABCDEF" : "0123456789abcdef"); + + /* Grows the Buffer size by 2 */ + grow_buff(buffer, buffer->len * 2); + + /* In-place modification must be done back-to-front to avoid + * overwriting the data while we read it. Even the order of + * the two assignments is important, to get i == 0 right. + */ + for (i = buffer->len - 1; i >= 0; i--) { + buffer->data[i * 2 + 1] = hexits[buffer->data[i] % 16]; + buffer->data[i * 2] = hexits[(buffer->data[i] / 16) & 0xf]; + } + + buffer->len = buffer->len * 2; + buffer->data[buffer->len] = '\0'; + + return TRUE; +} + +WBXML_DECLARE(WBXMLError) wbxml_buffer_decode_base64(WBXMLBuffer *buffer) +{ + WB_UTINY *result = NULL; + WB_LONG len = 0; + WBXMLError ret = WBXML_OK; + + if (buffer == NULL) { + return WBXML_ERROR_INTERNAL; + } + + wbxml_buffer_no_spaces(buffer); + + if ((len = wbxml_base64_decode((const WB_UTINY *) wbxml_buffer_get_cstr(buffer), + wbxml_buffer_len(buffer), &result)) <= 0) + { + return WBXML_ERROR_B64_DEC; + } + + /* Reset buffer */ + wbxml_buffer_delete(buffer, 0, wbxml_buffer_len(buffer)); + + /* Set binary data */ + if (!wbxml_buffer_append_data(buffer, result, len)) { + ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + wbxml_free(result); + + return ret; +} + +WBXML_DECLARE(WBXMLError) wbxml_buffer_encode_base64(WBXMLBuffer *buffer) +{ + WB_UTINY *result = NULL; + WBXMLError ret = WBXML_OK; + + if (buffer == NULL) { + return WBXML_ERROR_INTERNAL; + } + + if ((result = wbxml_base64_encode((const WB_UTINY *) wbxml_buffer_get_cstr(buffer), + wbxml_buffer_len(buffer))) == NULL) + { + return WBXML_ERROR_B64_ENC; + } + + /* Reset buffer */ + wbxml_buffer_delete(buffer, 0, wbxml_buffer_len(buffer)); + + /* Set data */ + if (!wbxml_buffer_append_cstr(buffer, result)) { + ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + wbxml_free(result); + + return ret; +} + +WBXML_DECLARE(void) wbxml_buffer_remove_trailing_zeros(WBXMLBuffer **buffer) +{ + WB_UTINY ch = 0; + + if ((buffer == NULL) || (*buffer == NULL)) + return; + + while ((*buffer)->len > 0) { + if (wbxml_buffer_get_char(*buffer, wbxml_buffer_len(*buffer) - 1, &ch) && (ch == '\0')) + wbxml_buffer_delete(*buffer, wbxml_buffer_len(*buffer) - 1, 1); + else + return; + } +} + + +/********************************** + * Private functions + */ + +/** + * @brief Add space for at least 'size' octets + * @param buffer The buffer + * @param size The size to add + * @return TRUE is space successfully reserved, FALSE is size was negative, buffer was NULL or if not enough memory + */ +static WB_BOOL grow_buff(WBXMLBuffer *buffer, WB_ULONG size) +{ + if ((buffer == NULL) || buffer->is_static) + return FALSE; + + /* Make room for the invisible terminating NUL */ + size++; + + if ((buffer->len + size) > buffer->malloced) { + if ((buffer->malloced * 2) < (buffer->len + size)) + buffer->malloced = buffer->len + size; + else + buffer->malloced *= 2; + + buffer->data = wbxml_realloc(buffer->data, buffer->malloced); + if (buffer->data == NULL) + return FALSE; + } + + return TRUE; +} + + +/** + * @brief Insert data into a Generic Buffer + * @param buffer The Generic Buffer + * @param pos Position in Generic Buffer where to insert data + * @param data Data to insert + * @param len Data length + * @return TRUE is data inserted, FALSE if not + */ +static WB_BOOL insert_data(WBXMLBuffer *buffer, WB_ULONG pos, const WB_UTINY *data, WB_ULONG len) +{ + if ((buffer == NULL) || buffer->is_static || (len == 0) || (pos > buffer->len)) + return FALSE; + + if (!grow_buff(buffer, len)) + return FALSE; + + if (buffer->len > pos) { + /* Only if neccessary */ + memmove(buffer->data + pos + len, buffer->data + pos, buffer->len - pos); + } + + memcpy(buffer->data + pos, data, len); + buffer->len += len; + buffer->data[buffer->len] = '\0'; + + return TRUE; +} diff --git a/src/wbxml_buffers.h b/src/wbxml_buffers.h new file mode 100644 index 0000000..f20f48a --- /dev/null +++ b/src/wbxml_buffers.h @@ -0,0 +1,341 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_buffers.h + * @ingroup wbxml_buffers + * + * @author Aymerick Jehanne + * @date 02/03/12 + * + * @brief Generic Buffers Functions + * + * @note Original idea: Kannel Project (http://kannel.3glab.org/) + */ + +#ifndef WBXML_BUFFERS_H +#define WBXML_BUFFERS_H + +#include + +#include "wbxml.h" +#include "wbxml_lists.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief WBXML Generic Buffer + */ +typedef struct WBXMLBuffer_s WBXMLBuffer; + + +/** @addtogroup wbxml_buffers + * @{ + */ + +/** + * @brief Create a Buffer + * @param data The initial data for buffer + * @param len Size of data + * @param malloc_block Size of the initial malloc block (tune this parameter to avoid too many reallocations) + * @return The newly created Buffer, or NULL if not enought memory + * @warning Do NOT use this function directly, use wbxml_buffer_create() macro instead + */ +WBXML_DECLARE(WBXMLBuffer *) wbxml_buffer_create_real(const WB_UTINY *data, WB_ULONG len, WB_ULONG malloc_block); + +/** Wrapper around wbxml_buffer_create_real() to track Memory */ +#define wbxml_buffer_create(a,b,c) \ + wbxml_mem_cleam(wbxml_buffer_create_real((const WB_UTINY *)a,b,c)) + +/** Wrapper around wbxml_buffer_create() when creating buffer with a C String (NULL Terminated) */ +#define wbxml_buffer_create_from_cstr(a) \ + wbxml_buffer_create((const WB_UTINY *)a,WBXML_STRLEN(a),WBXML_STRLEN(a)) + +/** + * @brief Create a static Buffer + * @param data Buffer data + * @param len Data lenght + * @return The newly created Buffer, or NULL if not enough memory + * @note A static buffer can't be modified, so do not use functions dedeicated to dynamic buffers + * as wbxml_buffer_insert() or wbxml_buffer_append() + * @warning Do NOT use this function directly, use wbxml_buffer_sta_create() macro instead + */ +WBXML_DECLARE(WBXMLBuffer *) wbxml_buffer_sta_create_real(const WB_UTINY *data, WB_ULONG len); + +/** Wrapper around wbxml_buffer_sta_create_real() to track Memory */ +#define wbxml_buffer_sta_create(a,b) \ + wbxml_mem_cleam(wbxml_buffer_sta_create_real((const WB_UTINY *)a,b)) + +/** Wrapper around wbxml_buffer_sta_create() when creating static buffer with a C String (NULL Terminated) */ +#define wbxml_buffer_sta_create_from_cstr(a) \ + wbxml_buffer_sta_create((const WB_UTINY *)a,WBXML_STRLEN(a)) + +/** + * @brief Destroy a Buffer + * @param buff The Buffer to destroy + */ +WBXML_DECLARE(void) wbxml_buffer_destroy(WBXMLBuffer *buff); + +/** + * @brief Destroy a Buffer (used for wbxml_list_destroy()) + * @param buff The Buffer to destroy + */ +WBXML_DECLARE_NONSTD(void) wbxml_buffer_destroy_item(void *buff); + +/** + * Duplicate a Buffer + * + * Even if a static buffer is provided, the duplicated buffer is + * a dynamic buffer. + * + * @param buff The Buffer to duplicate + * @return The duplicated buffer, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLBuffer *) wbxml_buffer_duplicate(WBXMLBuffer *buff); + +/** + * @brief Get data length of a buffer + * @param buff The Buffer + * @return The Buffer data length + */ +WBXML_DECLARE(WB_ULONG) wbxml_buffer_len(WBXMLBuffer *buff); + +/** + * @brief Get a byte from a Buffer + * @param buff The Buffer + * @param pos Byte position in buffer + * @param result The resulting char + * @return TRUE if OK, or FALSE if error + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_get_char(WBXMLBuffer *buff, WB_ULONG pos, WB_UTINY *result); + +/** + * @brief Set a byte in a dynamic Buffer + * @param buff The Buffer + * @param pos Byte position in buffer + * @param ch The character to set + */ +WBXML_DECLARE(void) wbxml_buffer_set_char(WBXMLBuffer *buff, WB_ULONG pos, WB_UTINY ch); + +/** + * @brief Get pointer to internal buffer data + * @param buff The Buffer + * @return Pointer to buffer data, or "" if buffer is NULL or empty + */ +WBXML_DECLARE(WB_UTINY *) wbxml_buffer_get_cstr(WBXMLBuffer *buff); + +/** + * @brief Insert a Buffer into a dynamic Buffer + * @param to The Buffer to modify + * @param buff The Buffer to insert + * @param pos The position of insertion in 'to' + * @return TRUE if data inserted, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_insert(WBXMLBuffer *to, WBXMLBuffer *buff, WB_ULONG pos); + +/** + * @brief Insert a C String into a dynamic Buffer + * @param to The Buffer to modify + * @param str The BC String to insert + * @param pos The position of insertion in 'to' + * @return TRUE if data inserted, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_insert_cstr(WBXMLBuffer *to, WB_UTINY *str, WB_ULONG pos); + +/** + * @brief Append a Buffer to a dynamic Buffer + * @param dest The destination Buffer + * @param buff The Buffer to append + * @return TRUE if buffer appended, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_append(WBXMLBuffer *dest, WBXMLBuffer *buff); + + +/** + * @brief Append data to a dynamic Buffer + * @param buff The Buffer + * @param data Data to append + * @param len Data length + * @return TRUE if data appended, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_data_real(WBXMLBuffer *buff, const WB_UTINY *data, WB_ULONG len); + +/** Wrapper around wbxml_buffer_append_data_real() to avoid Casts in code */ +#define wbxml_buffer_append_data(a,b,c) wbxml_buffer_append_data_real(a,(const WB_UTINY *)b,c) + +/** + * @brief Append a C String (NULL terminated) to a dynamic Buffer + * @param buff The Buffer + * @param data String to append + * @return TRUE if data appended, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_cstr_real(WBXMLBuffer *buff, const WB_UTINY *data); + +/** Wrapper around wbxml_buffer_append_cstr_real() to avoid Casts in code */ +#define wbxml_buffer_append_cstr(a,b) wbxml_buffer_append_cstr_real(a,(const WB_UTINY *)b) + + +/** + * @brief Append a byte to a dynamic Buffer + * @param buff The Buffer + * @param ch Byte to append + * @return TRUE if byte appended, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_char(WBXMLBuffer *buff, WB_UTINY ch); + +/** + * @brief Append a Multibyte Integer to a dynamic Buffer + * @param buff The Buffer + * @param value The value to append + * @return TRUE if value appended, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_mb_uint_32(WBXMLBuffer *buff, WB_ULONG value); + +/** + * @brief Delete a range of Bytes in a dynamicBuffer + * @param buff The Buffer + * @param pos Position where to start deletion + * @param len Number of bytes to delete + */ +WBXML_DECLARE(void) wbxml_buffer_delete(WBXMLBuffer *buff, WB_ULONG pos, WB_ULONG len); + +/** + * @brief Shrink all spaces in a dynamicBuffer + * @param buff The Buffer to shrink + * @note Replace every consecutive sequence of spaces into one unique whitespace + */ +WBXML_DECLARE(void) wbxml_buffer_shrink_blanks(WBXMLBuffer *buff); + +/** + * @brief Remove whitespaces at beginning and end of a dynamic Buffer + * @param buff The Buffer to strip + */ +WBXML_DECLARE(void) wbxml_buffer_strip_blanks(WBXMLBuffer *buff); + +/** + * @brief Compare two Buffers + * @param buff1 + * @param buff2 + * @return 0 if they are equal, negative if `buff1' is less than `buff2' and positive if greater + */ +WBXML_DECLARE(WB_LONG) wbxml_buffer_compare(WBXMLBuffer *buff1, WBXMLBuffer *buff2); + +/** + * @brief Compare a WBXML Buffer with a C String + * @param buff The WBXML Buffer + * @param str The C String + * @return 0 if they are equal, negative if `buff' is less than `str' and positive if greater + */ +WBXML_DECLARE(WB_LONG) wbxml_buffer_compare_cstr(WBXMLBuffer *buff, const WB_TINY *str); + +/** + * @brief Split a Buffer into words at whitespace + * @param buff The buffer to split + * @return The List of splitted Words, or NULL if not enough memory + * @warning Do NOT use this function directly, use wbxml_buffer_split_words() macro instead + */ +WBXML_DECLARE(WBXMLList *) wbxml_buffer_split_words_real(WBXMLBuffer *buff); +#define wbxml_buffer_split_words(a) wbxml_mem_cleam(wbxml_buffer_split_words_real(a)) + +/** + * @brief Search a char in Buffer + * @param to The buffer to search into + * @param ch The char to search + * @param pos Position to start searching in 'to' buffer + * @param result The start position of char in 'to' buffer + * @return TRUE if char successfully found in 'to' buffer, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_search_char(WBXMLBuffer *to, WB_UTINY ch, WB_ULONG pos, WB_ULONG *result); + +/** + * @brief Search a Buffer in another Buffer + * @param to The buffer to search into + * @param search The buffer to search + * @param pos Position to start searching in 'to' buffer + * @param result The start position of 'search' buffer in 'to' buffer + * @return TRUE if successfully found 'search' in 'to' buffer, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_search(WBXMLBuffer *to, WBXMLBuffer *search, WB_ULONG pos, WB_ULONG *result); + +/** + * @brief Search a C String in a WBXMLBuffer Buffer + * @param to The buffer to search into + * @param search The C String to search + * @param pos Position to start searching in 'to' buffer + * @param result The start position of 'search' buffer in 'to' buffer + * @return TRUE if successfully found 'search' in 'to' buffer, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_search_cstr(WBXMLBuffer *to, WB_UTINY *search, WB_ULONG pos, WB_ULONG *result); + +/** + * @brief Check if a buffer contains only Whitespaces + * @param buffer The buffer to check + * @return TRUE if it contains only whitespaces, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_contains_only_whitespaces(WBXMLBuffer *buffer); + +/** + * @brief Convert an Hexa dynamic buffer to Binary + * @param buffer The buffer to convert + */ +WBXML_DECLARE(void) wbxml_buffer_hex_to_binary(WBXMLBuffer *buffer); + +/** + * @brief Convert an Binary dynamic buffer to Hexa + * @param buffer The buffer to convert + * @param uppercase Do we convert to Uppercase Hexa ? + * @return TRUE if converted, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_buffer_binary_to_hex(WBXMLBuffer *buffer, WB_BOOL uppercase); + +/** + * @brief Convert base64 encoded data to binary data + * @param buffer The buffer to convert + * @return TRUE if converted, FALSE otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_buffer_decode_base64(WBXMLBuffer *buffer); + +/** + * @brief Convert binary data to base64 encoded data + * @param buffer The buffer to convert + * @return TRUE if converted, FALSE otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_buffer_encode_base64(WBXMLBuffer *buffer); + +/** + * @brief Remove trailing Zeros from a dynamic Buffer + * @param buffer The buffer + */ +WBXML_DECLARE(void) wbxml_buffer_remove_trailing_zeros(WBXMLBuffer **buffer); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_BUFFERS_H */ diff --git a/src/wbxml_charset.c b/src/wbxml_charset.c new file mode 100644 index 0000000..174d22b --- /dev/null +++ b/src/wbxml_charset.c @@ -0,0 +1,346 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_charset.c + * @ingroup wbxml_charset + * + * @author Aymerick Jehanne + * @date 04/03/24 + * + * @brief Charset Functions + */ + +#include "wbxml_charset.h" +#include "wbxml_internals.h" + +/* Structures */ + +/** WBXML Charset */ +typedef struct WBXMLCharsetEntry_s { + const WB_TINY *name; /**< Charset Name */ + WBXMLCharsetMIBEnum mib_enum; /**< Charset MIBEnum Value */ +} WBXMLCharsetEntry; + + +/* Globals */ + +/** + * @brief Charset table + * @note From http://www.iana.org/assignments/character-sets + */ +static const WBXMLCharsetEntry wbxml_charset_entries[] = +{ + { "US-ASCII", WBXML_CHARSET_US_ASCII }, + { "ISO-8859-1", WBXML_CHARSET_ISO_8859_1 }, + { "ISO-8859-2", WBXML_CHARSET_ISO_8859_2 }, + { "ISO-8859-3", WBXML_CHARSET_ISO_8859_3 }, + { "ISO-8859-4", WBXML_CHARSET_ISO_8859_4 }, + { "ISO-8859-5", WBXML_CHARSET_ISO_8859_5 }, + { "ISO-8859-6", WBXML_CHARSET_ISO_8859_6 }, + { "ISO-8859-7", WBXML_CHARSET_ISO_8859_7 }, + { "ISO-8859-8", WBXML_CHARSET_ISO_8859_8 }, + { "ISO-8859-9", WBXML_CHARSET_ISO_8859_9 }, + { "Shift_JIS", WBXML_CHARSET_SHIFT_JIS }, + { "UTF-8", WBXML_CHARSET_UTF_8 }, + { "ISO-10646-UCS-2", WBXML_CHARSET_ISO_10646_UCS_2 }, + { "UTF-16", WBXML_CHARSET_UTF_16 }, + { "Big5", WBXML_CHARSET_BIG5 } +}; + + +/* Private Functions Prototypes */ +static WB_BOOL search_null_block(const WB_TINY *in_buf, + WB_ULONG in_buf_len, + WB_ULONG block_len, + WB_ULONG *out_pos); + + +/*************************************************** + * Public Functions + */ + +WBXML_DECLARE(WB_BOOL) wbxml_charset_get_mib(const WB_TINY *name, + WBXMLCharsetMIBEnum *mib_enum) +{ + WB_ULONG i = 0; + + for (i = 0; i < WBXML_TABLE_SIZE(wbxml_charset_entries); i++) { + if (WBXML_STRCASECMP(name, wbxml_charset_entries[i].name) == 0) { + if (mib_enum != NULL) { + *mib_enum = wbxml_charset_entries[i].mib_enum; + } + + return TRUE; + } + } + + return FALSE; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_charset_get_name(WBXMLCharsetMIBEnum mib_enum, + const WB_TINY **name) +{ + WB_ULONG i = 0; + + for (i = 0; i < WBXML_TABLE_SIZE(wbxml_charset_entries); i++) { + if (mib_enum == wbxml_charset_entries[i].mib_enum) { + if (name != NULL) { + *name = wbxml_charset_entries[i].name; + } + + return TRUE; + } + } + + return FALSE; +} + + +WBXML_DECLARE(WBXMLError) wbxml_charset_conv(const WB_TINY *in_buf, + WB_ULONG *io_bytes, + WBXMLCharsetMIBEnum in_charset, + WBXMLBuffer **out_buf, + WBXMLCharsetMIBEnum out_charset) +{ + /************************************************** + * First, check for simple US-ASCII / UTF-8 cases + */ + + /* Are we dealing with US-ASCII or UTF-8 ? */ + if (((in_charset == WBXML_CHARSET_US_ASCII) || (in_charset == WBXML_CHARSET_UTF_8)) && + ((out_charset == WBXML_CHARSET_US_ASCII) || (out_charset == WBXML_CHARSET_UTF_8))) + { + /* Create a static buffer */ + if ((*out_buf = wbxml_buffer_sta_create_from_cstr(in_buf)) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* US-ASCII and UTF-8 are NULL terminated */ + *io_bytes -= WBXML_STRLEN(in_buf) + 1; + + return WBXML_OK; + } + + /************************************** + * Ok guys, we really have to convert + */ + +#if defined( HAVE_ICONV ) + + { + /********************** + * The iconv way + */ + + const WB_TINY * inbuf_pos = NULL; + WB_TINY **__restrict__ inbuf_ref = NULL; + const WB_TINY * charset_to = NULL; + const WB_TINY * charset_from = NULL; + WB_TINY * tmp_buf = NULL; + WB_TINY * tmp_ptr = NULL; + WB_ULONG tmp_buf_len = 0; + WB_ULONG tmp_len_left = 0; + WBXMLError ret = WBXML_OK; + iconv_t cd = 0; + WB_UTINY last_char = 0; + + /* Get Charsets names */ + if (!wbxml_charset_get_name(in_charset, &charset_from)) { + return WBXML_ERROR_CHARSET_UNKNOWN; + } + + if (!wbxml_charset_get_name(out_charset, &charset_to)) { + return WBXML_ERROR_CHARSET_UNKNOWN; + } + + /* Init iconv */ + if ((cd = iconv_open(charset_to, charset_from)) == (iconv_t)(-1)) + { + /* Init failed */ + return WBXML_ERROR_CHARSET_CONV_INIT; + } + + /* Allocate maximum result buffer (4 bytes unicode) */ + tmp_len_left = tmp_buf_len = 4 * (sizeof(WB_TINY) * (*io_bytes)); + + if ((tmp_buf = (WB_TINY *) wbxml_malloc(tmp_buf_len)) == NULL) { + iconv_close(cd); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + tmp_ptr = tmp_buf; + + /* The input buffer is const but not the pointer itself. + The original const *inbuf should not be modified for a potential later usage. + */ + inbuf_pos = in_buf; + inbuf_ref = (WB_TINY **__restrict__) &inbuf_pos; + + /* Convert ! */ + (void) iconv(cd, + inbuf_ref, + (size_t*)io_bytes, + &tmp_buf, + (size_t*)&tmp_len_left); + + /** @todo Check errno (but it doesn't seems to work on windows) */ + + if (tmp_buf_len > tmp_len_left) { + /* Create result buffer */ + if ((*out_buf = wbxml_buffer_create(tmp_ptr, + tmp_buf_len - tmp_len_left, + tmp_buf_len - tmp_len_left)) == NULL) + { + /* Not enough memory */ + ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Remove trailing NULL char */ + wbxml_buffer_remove_trailing_zeros(out_buf); + } + else + { + /* Not converted */ + ret = WBXML_ERROR_CHARSET_CONV; + } + + /* Shutdown iconv */ + iconv_close(cd); + + /* Clean-up */ + wbxml_free(tmp_ptr); + + return ret; + } + +#else + + { + /*************************************************** + * Add your own charset conversion function here ! + */ + + return WBXML_ERROR_NO_CHARSET_CONV; + } + +#endif /* HAVE_ICONV */ +} + + +WBXML_DECLARE(WBXMLError) wbxml_charset_conv_term(const WB_TINY *in_buf, + WB_ULONG *io_bytes, + WBXMLCharsetMIBEnum in_charset, + WBXMLBuffer **out_buf, + WBXMLCharsetMIBEnum out_charset) +{ + WB_ULONG buf_len = 0; + WB_ULONG new_len = 0; + WB_ULONG term_len = 0; + WBXMLError ret = WBXML_OK; + + /* Find length of input buffer */ + switch (in_charset) + { + case WBXML_CHARSET_ISO_10646_UCS_2 : + case WBXML_CHARSET_UTF_16 : + /* Terminated by two NULL char ("\0\0") */ + term_len = 2; + + if (!search_null_block(in_buf, *io_bytes, 2, &buf_len)) { + return WBXML_ERROR_CHARSET_STR_LEN; + } + + /* Add termination bytes length */ + buf_len += term_len; + break; + + default : + /* Terminated by a simple NULL char ('\0') */ + term_len = 1; + + buf_len = WBXML_STRLEN(in_buf) + term_len; + break; + } + + /* Check length found */ + if (buf_len > *io_bytes) { + return WBXML_ERROR_CHARSET_STR_LEN; + } + + /* Use a temporary length var (because it is decreased) */ + new_len = buf_len; + + /* Convert ! */ + ret = wbxml_charset_conv(in_buf, + &new_len, + in_charset, + out_buf, + out_charset); + + /* Set input buffer length */ + *io_bytes = buf_len; + + return ret; +} + + +/*************************************************** + * Private Functions + */ + +/** + * Binary search of a sequence of NULL bytes in a buffer + * + * @param in_buf Buffer to search in + * @param in_buf_len Length of input buffer + * @param block_len Length of the NULL sequence + * @param out_pos Index of Sequence into Buffer + * @return TRUE if found, FALSE otherwise + */ +static WB_BOOL search_null_block(const WB_TINY *in_buf, + WB_ULONG in_buf_len, + WB_ULONG block_len, + WB_ULONG *out_pos) +{ + WB_ULONG pos = 0; + WB_ULONG i = 0; + + for (pos = 0; pos + block_len <= in_buf_len; pos += block_len) { + for (i = 0; i < block_len; i++) { + if (memcmp(in_buf + pos + i, "\0", 1)) { + i = block_len; + } else { + if (i == block_len -1) { + *out_pos = pos; + return TRUE; + } + } + } + } + + return FALSE; +} diff --git a/src/wbxml_charset.h b/src/wbxml_charset.h new file mode 100644 index 0000000..59508d0 --- /dev/null +++ b/src/wbxml_charset.h @@ -0,0 +1,126 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_charset.h + * @ingroup wbxml_charset + * + * @author Aymerick Jehanne + * @date 04/03/24 + * + * @brief Charset Functions + */ + +#ifndef WBXML_CHARSET_H +#define WBXML_CHARSET_H + +#include "wbxml.h" +#include "wbxml_buffers.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_charset + * @{ + */ + + +/** + * @brief Get a Charset MIBEnum given a Charset Name + * @param name [in] Charset Name to search + * @param mib_enum [out] MIBEnum if found + * @return Return TRUE if Charset found, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_charset_get_mib(const WB_TINY *name, + WBXMLCharsetMIBEnum *mib_enum); + +/** + * @brief Get a Charset Name given a Charset MIBEnum + * @param mib_enum [in] MIBEnum to search + * @param name [out] Charset Name if found + * @return Return TRUE if Charset found, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_charset_get_name(WBXMLCharsetMIBEnum mib_enum, + const WB_TINY **name); + +/** + * Charset Convertion function + * + * Input is a normal pointer to buffer to convert. + * + * Result is a WBXML Buffer. If 'in_charset' and 'out_charset' are + * identical, and are even ASCII or UTF-8, this will be a static + * buffer pointing to input buffer. + * + * The 'io_bytes' parameter is decremented each time a byte is correctly + * converted from 'in_buf', so that it reflects the number of bytes that + * have been converted from 'in_buf'. + * + * @param in_buf Buffer to convert + * @param io_bytes Number of bytes in buffer + * @param in_charset Original charset + * @param out_buf Resulting converted Buffer + * @param out_charset Destination charset + */ +WBXML_DECLARE(WBXMLError) wbxml_charset_conv(const WB_TINY *in_buf, + WB_ULONG *io_bytes, + WBXMLCharsetMIBEnum in_charset, + WBXMLBuffer **out_buf, + WBXMLCharsetMIBEnum out_charset); + +/** + * Charset Convertion function, for unknown length strings + * + * This is a wrapper around wbxml_charset_conv(), but to convert + * a buffer that have an unknown length. This function first try to find + * the buffer length, by finding its charset specific termination code + * (eg: '\0', '\0\0'), then it calls the wbxml_charset_conv() function. + * + * Set the maximum possible length of input buffer into 'io_bytes'. A check + * is done if length found is higher than input 'io_bytes' value. + * + * WARNING : 'io_bytes' is then set to the real length of input buffer (this is + * a different behaviour than with wbxml_charset_conv()). + * + * @param in_buf Buffer to convert + * @param io_bytes Number of bytes in buffer + * @param in_charset Original charset + * @param out_buf Resulting converted Buffer + * @param out_charset Destination charset + */ +WBXML_DECLARE(WBXMLError) wbxml_charset_conv_term(const WB_TINY *in_buf, + WB_ULONG *io_bytes, + WBXMLCharsetMIBEnum in_charset, + WBXMLBuffer **out_buf, + WBXMLCharsetMIBEnum out_charset); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_CHARSET_H */ diff --git a/src/wbxml_config.h.cmake b/src/wbxml_config.h.cmake new file mode 100644 index 0000000..7b91758 --- /dev/null +++ b/src/wbxml_config.h.cmake @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2008 Michael Bell + */ + +#ifndef WBXML_CONFIG_H +#define WBXML_CONFIG_H + +/** WBXML Parser Lib Version */ +#define WBXML_LIB_VERSION "${PACKAGE_VERSION}" + +/* Define to 1 if you would like to enable debug, warning and error messages */ +#cmakedefine WBXML_LIB_VERBOSE + +/* supported document types */ +#cmakedefine WBXML_ENCODER_USE_STRTBL +#cmakedefine WBXML_SUPPORT_WML +#cmakedefine WBXML_SUPPORT_WTA +#cmakedefine WBXML_SUPPORT_SI +#cmakedefine WBXML_SUPPORT_SL +#cmakedefine WBXML_SUPPORT_CO +#cmakedefine WBXML_SUPPORT_PROV +#cmakedefine WBXML_SUPPORT_EMN +#cmakedefine WBXML_SUPPORT_DRMREL +#cmakedefine WBXML_SUPPORT_OTA_SETTINGS +#cmakedefine WBXML_SUPPORT_SYNCML +#cmakedefine WBXML_SUPPORT_WV +#cmakedefine WBXML_SUPPORT_AIRSYNC +#cmakedefine WBXML_SUPPORT_CONML + +#endif /* WBXML_CONFIG_H */ diff --git a/src/wbxml_config_internals.h.cmake b/src/wbxml_config_internals.h.cmake new file mode 100644 index 0000000..a1a139d --- /dev/null +++ b/src/wbxml_config_internals.h.cmake @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2008 Michael Bell + */ + +#ifndef WBXML_CONFIG_INTERNALS_H +#define WBXML_CONFIG_INTERNALS_H + +/* These are the public details of the configuration. */ +#include "wbxml_config.h" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#cmakedefine HAVE_DOPRNT + +/* Define to 1 if you have the header file. */ +/* Define to 1 if you have the `expat' library (-lexpat). */ +#cmakedefine HAVE_EXPAT + +/* Define to 1 if you have the `iconv' library (sometimes in libc). */ +#cmakedefine HAVE_ICONV + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#cmakedefine HAVE_LIBNSL + +/* Define to 1 if you have the `popt' library (-lpopt). */ +#cmakedefine HAVE_LIBPOPT + +/* Define to 1 if you have the `z' library (-lz). */ +#cmakedefine HAVE_LIBZ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#cmakedefine HAVE_VPRINTF + +/* Name of package */ +#cmakedefine PACKAGE "${PACKAGE}" + +/* Define to the address where bug reports for this package should be sent. */ +#cmakedefine PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}" + +/* Define to the full name of this package. */ +#cmakedefine PACKAGE_NAME "${PACKAGE_NAME}" + +/* Define to the full name and version of this package. */ +#cmakedefine PACKAGE_STRING "${PACKAGE_STRING}" + +/* Define to the one symbol short name of this package. */ +#cmakedefine PACKAGE_TARNAME "${PACKAGE_TARNAME}" + +/* Define to the version of this package. */ +#cmakedefine PACKAGE_VERSION "${PACKAGE_VERSION}" + +/* Define to 1 if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS 1 + +/* Version number of package */ +#cmakedefine VERSION "${VERSION}" + +/* Define to empty if `const' does not conform to ANSI C. */ +#cmakedefine const + +/* Define to `unsigned int' if does not define. */ +#cmakedefine size_t + +/* Includes */ +#if defined( HAVE_EXPAT) +#include +#endif /* HAVE_EXPAT */ + +#if defined( HAVE_ICONV ) +#include +#endif /* HAVE_ICONV */ + + +#endif /* WBXML_CONFIG_INTERNALS_H */ diff --git a/src/wbxml_conv.c b/src/wbxml_conv.c new file mode 100644 index 0000000..d436e82 --- /dev/null +++ b/src/wbxml_conv.c @@ -0,0 +1,378 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_conv.c + * @ingroup wbxml_conv + * + * @author Aymerick Jehanne + * @date 03/02/23 + * + * @brief WBXML Convertion Library (XML to WBXML, and WBXML to XML) + */ + +#include "wbxml_conv.h" +#include "wbxml_tree.h" +#include "wbxml_log.h" + +/**************************** + * converter objects * + **************************** + */ + +struct WBXMLConvWBXML2XML_s { + WBXMLGenXMLType gen_type; /**< WBXML_GEN_XML_COMPACT | WBXML_GEN_XML_INDENT | WBXML_GEN_XML_CANONICAL (Default: WBXML_GEN_XML_INDENT) */ + WBXMLLanguage lang; /**< Force document Language (overwrite document Public ID) */ + WBXMLCharsetMIBEnum charset; /**< Set document Language (does not overwrite document character set) */ + WB_UTINY indent; /**< Indentation Delta, when using WBXML_GEN_XML_INDENT Generation Type (Default: 0) */ + WB_BOOL keep_ignorable_ws; /**< Keep Ignorable Whitespaces (Default: FALSE) */ +}; + +struct WBXMLConvXML2WBXML_s { + WBXMLVersion wbxml_version; /**< WBXML Version */ + WB_BOOL keep_ignorable_ws; /**< Keep Ignorable Whitespaces (Default: FALSE) */ + WB_BOOL use_strtbl; /**< Generate String Table (Default: TRUE) */ + WB_BOOL produce_anonymous; /**< Produce an anonymous document (Default: FALSE) */ +}; + +/**************************** + * Public Functions * + **************************** + */ + +WBXML_DECLARE(WBXMLError) wbxml_conv_wbxml2xml_create(WBXMLConvWBXML2XML **conv) +{ + *conv = (WBXMLConvWBXML2XML *) wbxml_malloc(sizeof(WBXMLConvWBXML2XML)); + if (conv == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + (*conv)->gen_type = WBXML_GEN_XML_INDENT; + (*conv)->lang = WBXML_LANG_UNKNOWN; + (*conv)->charset = WBXML_CHARSET_UNKNOWN; + (*conv)->indent = 0; + (*conv)->keep_ignorable_ws = FALSE; + + return WBXML_OK; +} + +/** + * @brief Set the XML generation type (default: WBXML_GEN_XML_INDENT). + * @param conv [in] the converter + * @param gen_type [in] generation type + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_set_gen_type(WBXMLConvWBXML2XML *conv, WBXMLGenXMLType gen_type) +{ + conv->gen_type = gen_type; +} + +/** + * @brief Set the used WBXML language. + * The language is usually detected by the specified public ID in the document. + * If the public ID is set then it overrides the language. + * @param conv [in] the converter + * @param lang [in] language (e.g. SYNCML12) + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_set_language(WBXMLConvWBXML2XML *conv, WBXMLLanguage lang) +{ + conv->lang = lang; +} + +/** + * @brief Set the used character set. + * The default character set is UTF-8. + * If the document specifies a character set by it own + * then this character set overrides the parameter charset. + * @param conv [in] the converter + * @param charset [in] the character set + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_set_charset(WBXMLConvWBXML2XML *conv, WBXMLCharsetMIBEnum charset) +{ + conv->charset = charset; +} + +/** + * @brief Set the indent of the generated XML document (please see EXPAT default). + * @param conv [in] the converter + * @param indent [in] the number of blanks + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_set_indent(WBXMLConvWBXML2XML *conv, WB_UTINY indent) +{ + conv->indent = indent; +} + +/** + * @brief Enable whitespace preservation (default: FALSE). + * @param conv [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_enable_preserve_whitespaces(WBXMLConvWBXML2XML *conv) +{ + conv->keep_ignorable_ws = TRUE; +} + +/** + * @brief Convert WBXML to XML + * @param conv [in] the converter + * @param wbxml [in] WBXML Document to convert + * @param wbxml_len [in] Length of WBXML Document + * @param xml [out] Resulting XML Document + * @param xml_len [out] XML Document length + * @return WBXML_OK if conversion succeeded, an Error Code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_conv_wbxml2xml_run(WBXMLConvWBXML2XML *conv, + WB_UTINY *wbxml, + WB_ULONG wbxml_len, + WB_UTINY **xml, + WB_ULONG *xml_len) +{ + WBXMLGenXMLParams params; + WBXMLTree *wbxml_tree = NULL; + WB_ULONG dummy_len = 0; + WBXMLError ret = WBXML_OK; + + /* Copy options */ + params.gen_type = conv->gen_type; + params.lang = conv->lang; + params.charset = conv->charset; + params.keep_ignorable_ws = conv->keep_ignorable_ws; + params.indent = conv->indent; + + /* Check Parameters (we allow 'xml_len' to be NULL for backward compatibility) */ + if ((wbxml == NULL) || (wbxml_len == 0) || (xml == NULL)) + return WBXML_ERROR_BAD_PARAMETER; + + if (xml_len == NULL) + xml_len = &dummy_len; + + *xml = NULL; + *xml_len = 0; + + /* Parse WBXML to WBXML Tree */ + ret = wbxml_tree_from_wbxml(wbxml, wbxml_len, conv->lang, conv->charset, &wbxml_tree); + if (ret != WBXML_OK) { + WBXML_ERROR((WBXML_CONV, "wbxml2xml conversion failed - WBXML Parser Error: %s", + wbxml_errors_string(ret))); + + return ret; + } + else { + /* Convert Tree to XML */ + ret = wbxml_tree_to_xml(wbxml_tree, xml, xml_len, ¶ms); + if (ret != WBXML_OK) { + WBXML_ERROR((WBXML_CONV, "wbxml2xml conversion failed - WBXML Encoder Error: %s", + wbxml_errors_string(ret))); + } + + /* Clean-up */ + wbxml_tree_destroy(wbxml_tree); + + return ret; + } +} + +/** + * @brief Destroy the converter object. + * @param [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_destroy(WBXMLConvWBXML2XML *conv) +{ + wbxml_free(conv); +} + +/** + * @brief Create a new WBXML to XML converter with the default configuration. + * @param conv [out] a reference to the pointer of the new converter + * @return WBXML_OK if conversion succeeded, an Error Code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_conv_xml2wbxml_create(WBXMLConvXML2WBXML **conv) +{ + *conv = (WBXMLConvXML2WBXML *) wbxml_malloc(sizeof(WBXMLConvXML2WBXML)); + if (conv == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + (*conv)->wbxml_version = WBXML_VERSION_13; + (*conv)->keep_ignorable_ws = FALSE; + (*conv)->use_strtbl = TRUE; + (*conv)->produce_anonymous = FALSE; + + return WBXML_OK; +} + +/** + * @brief Set the WBXML version (default: 1.3). + * @param conv [in] the converter + * @param indent [in] the number of blanks + */ +WBXML_DECLARE(void) wbxml_conv_xml2wbxml_set_version(WBXMLConvXML2WBXML *conv, + WBXMLVersion wbxml_version) +{ + conv->wbxml_version = wbxml_version; +} + +/** + * @brief Enable whitespace preservation (default: FALSE/DISABLED). + * @param conv [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_xml2wbxml_enable_preserve_whitespaces(WBXMLConvXML2WBXML *conv) +{ + conv->keep_ignorable_ws = TRUE; +} + +/** + * @brief Disable string table (default: TRUE/ENABLED). + * @param conv [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_xml2wbxml_disable_string_table(WBXMLConvXML2WBXML *conv) +{ + conv->use_strtbl = FALSE; +} + +/** + * @brief Disable public ID (default: TRUE/ENABLED). + * @param conv [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_xml2wbxml_disable_public_id(WBXMLConvXML2WBXML *conv) +{ + conv->produce_anonymous = TRUE; +} + +/** + * @brief Convert XML to WBXML + * @param conv [in] the converter + * @param xml [in] XML Document to convert + * @param xml_len [in] Length of XML Document + * @param wbxml [out] Resulting WBXML Document + * @param wbxml_len [out] Length of resulting WBXML Document + * @return WBXML_OK if conversion succeeded, an Error Code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_conv_xml2wbxml_run(WBXMLConvXML2WBXML *conv, + WB_UTINY *xml, + WB_ULONG xml_len, + WB_UTINY **wbxml, + WB_ULONG *wbxml_len) +{ + WBXMLTree *wbxml_tree = NULL; + WBXMLError ret = WBXML_OK; + WBXMLGenWBXMLParams params; + + /* Check Parameters */ + if ((xml == NULL) || (xml_len == 0) || (wbxml == NULL) || (wbxml_len == NULL)) + return WBXML_ERROR_BAD_PARAMETER; + + /* copy options */ + params.wbxml_version = conv->wbxml_version; + params.keep_ignorable_ws = conv->keep_ignorable_ws; + params.use_strtbl = conv->use_strtbl; + params.produce_anonymous = conv->produce_anonymous; + + *wbxml = NULL; + *wbxml_len = 0; + + /* Parse XML to WBXML Tree */ + ret = wbxml_tree_from_xml(xml, xml_len, &wbxml_tree); + if (ret != WBXML_OK) { + WBXML_ERROR((WBXML_CONV, "xml2wbxml conversion failed - Error: %s", + wbxml_errors_string(ret))); + + return ret; + } + else { + /* Convert Tree to WBXML */ + ret = wbxml_tree_to_wbxml(wbxml_tree, wbxml, wbxml_len, ¶ms); + if (ret != WBXML_OK) { + WBXML_ERROR((WBXML_CONV, "xml2wbxml conversion failed - WBXML Encoder Error: %s", + wbxml_errors_string(ret))); + } + + /* Clean-up */ + wbxml_tree_destroy(wbxml_tree); + + return ret; + } +} + + +/** + * @brief Destroy the converter object. + * @param [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_xml2wbxml_destroy(WBXMLConvXML2WBXML *conv) +{ + wbxml_free(conv); +} + +/************************************** + * Public Functions - DEPRECATED in API + */ + +WBXML_DECLARE(WBXMLError) wbxml_conv_wbxml2xml_withlen(WB_UTINY *wbxml, + WB_ULONG wbxml_len, + WB_UTINY **xml, + WB_ULONG *xml_len, + WBXMLGenXMLParams *params) +{ + WBXMLConvWBXML2XML *conv = NULL; + WBXMLError ret = WBXML_OK; + + ret = wbxml_conv_wbxml2xml_create(&conv); + if (ret != WBXML_OK) + return ret; + + wbxml_conv_wbxml2xml_set_gen_type(conv, params->gen_type); + wbxml_conv_wbxml2xml_set_language(conv, params->lang); + wbxml_conv_wbxml2xml_set_charset(conv, params->charset); + wbxml_conv_wbxml2xml_set_indent(conv, params->indent); + if (params->keep_ignorable_ws) + wbxml_conv_wbxml2xml_enable_preserve_whitespaces(conv); + ret = wbxml_conv_wbxml2xml_run(conv, wbxml, wbxml_len, xml, xml_len); + wbxml_conv_wbxml2xml_destroy(conv); + return ret; +} + +WBXML_DECLARE(WBXMLError) wbxml_conv_xml2wbxml_withlen(WB_UTINY *xml, + WB_ULONG xml_len, + WB_UTINY **wbxml, + WB_ULONG *wbxml_len, + WBXMLGenWBXMLParams *params) +{ + WBXMLConvXML2WBXML *conv = NULL; + WBXMLError ret = WBXML_OK; + + ret = wbxml_conv_xml2wbxml_create(&conv); + if (ret != WBXML_OK) + return ret; + + wbxml_conv_xml2wbxml_set_version(conv, params->wbxml_version); + if (params->keep_ignorable_ws) + wbxml_conv_xml2wbxml_enable_preserve_whitespaces(conv); + if (!params->use_strtbl) + wbxml_conv_xml2wbxml_disable_string_table(conv); + if (params->produce_anonymous) + wbxml_conv_xml2wbxml_disable_public_id(conv); + ret = wbxml_conv_xml2wbxml_run(conv, xml, xml_len, wbxml, wbxml_len); + wbxml_conv_xml2wbxml_destroy(conv); + return ret; +} diff --git a/src/wbxml_conv.h b/src/wbxml_conv.h new file mode 100644 index 0000000..d250a3b --- /dev/null +++ b/src/wbxml_conv.h @@ -0,0 +1,414 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_conv.h + * @ingroup wbxml_conv + * + * @author Aymerick Jehanne + * @date 03/02/23 + * + * @brief WBXML Convertion Library (XML to WBXML, and WBXML to XML) + */ + +#ifndef WBXML_CONV_H +#define WBXML_CONV_H + +#include "wbxml.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_conv + * @{ + */ + +/** WBXML Versions (WBXML tokens) */ +typedef enum WBXMLVersion_e { + WBXML_VERSION_UNKNOWN = -1, /**< Unknown WBXML Version */ + WBXML_VERSION_10 = 0x00, /**< WBXML 1.0 Token */ + WBXML_VERSION_11 = 0x01, /**< WBXML 1.1 Token */ + WBXML_VERSION_12 = 0x02, /**< WBXML 1.2 Token */ + WBXML_VERSION_13 = 0x03 /**< WBXML 1.3 Token */ +} WBXMLVersion; + + +/* + * Possible Compilation Flags: + * --------------------------- + * + * WBXML_SUPPORT_WML + * WBXML_SUPPORT_WTA + * WBXML_SUPPORT_SI + * WBXML_SUPPORT_SL + * WBXML_SUPPORT_CO + * WBXML_SUPPORT_PROV + * WBXML_SUPPORT_EMN + * WBXML_SUPPORT_DRMREL + * WBXML_SUPPORT_OTA_SETTINGS + * WBXML_SUPPORT_SYNCML + * WBXML_SUPPORT_WV + * WBXML_SUPPORT_AIRSYNC + * WBXML_SUPPORT_CONML + */ + + +/** Supported WBXML Languages */ +typedef enum WBXMLLanguage_e { + WBXML_LANG_UNKNOWN = 0, /**< Unknown / Not Specified */ + + /* WAP */ +#if defined( WBXML_SUPPORT_WML ) + WBXML_LANG_WML10 = 1101, /**< WML 1.0 */ + WBXML_LANG_WML11 = 1102, /**< WML 1.1 */ + WBXML_LANG_WML12 = 1103, /**< WML 1.2 */ + WBXML_LANG_WML13 = 1104, /**< WML 1.3 */ +#endif /* WBXML_SUPPORT_WML */ + +#if defined( WBXML_SUPPORT_WTA ) + WBXML_LANG_WTA10 = 1201, /**< WTA 1.0 */ + WBXML_LANG_WTAWML12 = 1202, /**< WTAWML 1.2 */ + WBXML_LANG_CHANNEL11 = 1203, /**< CHANNEL 1.1 */ + WBXML_LANG_CHANNEL12 = 1204, /**< CHANNEL 1.2 */ +#endif /* WBXML_SUPPORT_WTA */ + +#if defined( WBXML_SUPPORT_SI ) + WBXML_LANG_SI10 = 1301, /**< SI 1.0 */ +#endif /* WBXML_SUPPORT_SI */ + +#if defined( WBXML_SUPPORT_SL ) + WBXML_LANG_SL10 = 1401, /**< SL 1.0 */ +#endif /* WBXML_SUPPORT_SL */ + +#if defined( WBXML_SUPPORT_CO ) + WBXML_LANG_CO10 = 1501, /**< CO 1.0 */ +#endif /* WBXML_SUPPORT_CO */ + +#if defined( WBXML_SUPPORT_PROV ) + WBXML_LANG_PROV10 = 1601, /**< PROV 1.0 */ +#endif /* WBXML_SUPPORT_PROV */ + +#if defined( WBXML_SUPPORT_EMN ) + WBXML_LANG_EMN10 = 1701, /**< EMN 1.0 */ +#endif /* WBXML_SUPPORT_EMN */ + +#if defined( WBXML_SUPPORT_DRMREL ) + WBXML_LANG_DRMREL10 = 1801, /**< DRMREL 1.0 */ +#endif /* WBXML_SUPPORT_DRMREL */ + +#if defined( WBXML_SUPPORT_OTA_SETTINGS ) + /* Ericsson / Nokia OTA Settings v7.0 */ + WBXML_LANG_OTA_SETTINGS = 1901, /**< OTA Settings */ +#endif /* WBXML_SUPPORT_OTA_SETTINGS */ + + /* SyncML */ +#if defined( WBXML_SUPPORT_SYNCML ) + WBXML_LANG_SYNCML_SYNCML10 = 2001, /**< SYNCML 1.0 */ + WBXML_LANG_SYNCML_DEVINF10 = 2002, /**< DEVINF 1.0 */ + WBXML_LANG_SYNCML_METINF10 = 2003, /**< METINF 1.0 */ + + WBXML_LANG_SYNCML_SYNCML11 = 2101, /**< SYNCML 1.1 */ + WBXML_LANG_SYNCML_DEVINF11 = 2102, /**< DEVINF 1.1 */ + WBXML_LANG_SYNCML_METINF11 = 2103, /**< METINF 1.1 */ + + WBXML_LANG_SYNCML_SYNCML12 = 2201, /**< SYNCML 1.2 */ + WBXML_LANG_SYNCML_DEVINF12 = 2202, /**< DEVINF 1.2 */ + WBXML_LANG_SYNCML_METINF12 = 2203, /**< METINF 1.2 */ + WBXML_LANG_SYNCML_DMDDF12 = 2204, /**< DMDDF 1.2 */ +#endif /* WBXML_SUPPORT_SYNCML */ + + /* Wireless-Village */ +#if defined( WBXML_SUPPORT_WV ) + WBXML_LANG_WV_CSP11 = 2301, /**< WV CSP 1.1 */ + WBXML_LANG_WV_CSP12 = 2302, /**< WV CSP 1.2 */ +#endif /* WBXML_SUPPORT_WV */ + + /* Microsoft AirSync */ +#if defined( WBXML_SUPPORT_AIRSYNC ) + WBXML_LANG_AIRSYNC = 2401, /**< AirSync */ + WBXML_LANG_ACTIVESYNC = 2402, /**< ActiveSync */ +#endif /* WBXML_SUPPORT_AIRSYNC */ + + /* Nokia ConML */ +#if defined( WBXML_SUPPORT_CONML ) + WBXML_LANG_CONML = 2501 /**< ConML */ +#endif /* WBXML_SUPPORT_CONML */ +} WBXMLLanguage; + + +/** Supported WBXML Charsets MIBEnum */ +typedef enum WBXMLCharsetMIBEnum_e { + WBXML_CHARSET_UNKNOWN = 0, /**< Unknown Charset */ + WBXML_CHARSET_US_ASCII = 3, /**< US-ASCII */ + WBXML_CHARSET_ISO_8859_1 = 4, /**< ISO-8859-1 */ + WBXML_CHARSET_ISO_8859_2 = 5, /**< ISO-8859-2 */ + WBXML_CHARSET_ISO_8859_3 = 6, /**< ISO-8859-3 */ + WBXML_CHARSET_ISO_8859_4 = 7, /**< ISO-8859-4 */ + WBXML_CHARSET_ISO_8859_5 = 8, /**< ISO-8859-5 */ + WBXML_CHARSET_ISO_8859_6 = 9, /**< ISO-8859-6 */ + WBXML_CHARSET_ISO_8859_7 = 10, /**< ISO-8859-7 */ + WBXML_CHARSET_ISO_8859_8 = 11, /**< ISO-8859-8 */ + WBXML_CHARSET_ISO_8859_9 = 12, /**< ISO-8859-9 */ + WBXML_CHARSET_SHIFT_JIS = 17, /**< Shift_JIS */ + WBXML_CHARSET_UTF_8 = 106, /**< UTF-8 */ + WBXML_CHARSET_ISO_10646_UCS_2 = 1000, /**< ISO-10646-UCS-2 */ + WBXML_CHARSET_UTF_16 = 1015, /**< UTF-16 */ + WBXML_CHARSET_BIG5 = 2026 /**< Big5 */ +} WBXMLCharsetMIBEnum; + + +/** + * @brief Type of XML Generation + * @note Canonical Form is defined here: http://www.jclark.com/xml/canonxml.html + */ +typedef enum WBXMLGenXMLType_e { + WBXML_GEN_XML_COMPACT = 0, /**< Compact XML generation */ + WBXML_GEN_XML_INDENT = 1, /**< Indented XML generation */ + WBXML_GEN_XML_CANONICAL = 2 /**< Canonical XML generation */ +} WBXMLGenXMLType; + + +/** + * @brief Parameters when generating an XML document + */ +typedef struct WBXMLGenXMLParams_s { + WBXMLGenXMLType gen_type; /**< WBXML_GEN_XML_COMPACT | WBXML_GEN_XML_INDENT | WBXML_GEN_XML_CANONICAL (Default: WBXML_GEN_XML_INDENT) */ + WBXMLLanguage lang; /**< Force document Language (overwrite document Public ID) */ + WBXMLCharsetMIBEnum charset; /**< Set document Language (does not overwrite document character set) */ + WB_UTINY indent; /**< Indentation Delta, when using WBXML_GEN_XML_INDENT Generation Type (Default: 0) */ + WB_BOOL keep_ignorable_ws; /**< Keep Ignorable Whitespaces (Default: FALSE) */ +} WBXMLGenXMLParams; + +/** + * @brief Parameters when generating a WBXML document + */ +typedef struct WBXMLGenWBXMLParams_s { + WBXMLVersion wbxml_version; /**< WBXML Version */ + WB_BOOL keep_ignorable_ws; /**< Keep Ignorable Whitespaces (Default: FALSE) */ + WB_BOOL use_strtbl; /**< Generate String Table (Default: TRUE) */ + WB_BOOL produce_anonymous; /**< Produce an anonymous document (Default: FALSE) */ +} WBXMLGenWBXMLParams; + +/** + * Wrapper around wbxml_conv_wbxml2_withlen() + * + * This macro is provided for backward compatibility. You can use it if you are + * sure that the output XML document will be encoded in a charset that is NULL + * terminated and that can't contains any NULL character in it. For example + * this macro works for US-ASCII or UTF-8 encoded documents, but not for UTF-16 + * encoded documents. + */ +#define wbxml_conv_wbxml2xml(a,b,c,d) wbxml_conv_wbxml2xml_withlen(a,b,c,NULL,d) + +/** + * @brief Convert WBXML to XML + * @param wbxml [in] WBXML Document to convert + * @param wbxml_len [in] Length of WBXML Document + * @param xml [out] Resulting XML Document + * @param xml_len [out] XML Document length + * @param params [in] Parameters (if NULL, default values are used) + * @return WBXML_OK if conversion succeeded, an Error Code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_conv_wbxml2xml_withlen(WB_UTINY *wbxml, + WB_ULONG wbxml_len, + WB_UTINY **xml, + WB_ULONG *xml_len, + WBXMLGenXMLParams *params) LIBWBXML_DEPRECATED; + +/** + * Wrapper around wbxml_conv_xml2wbxml_withlen() + * + * This macro is provided for backward compatibility. You can use it if you are + * sure that the input XML document is encoded in a charset that is NULL terminated + * and that can't contains any NULL character in it. For example this macro + * works for US-ASCII or UTF-8 encoded documents, but not for UTF-16 encoded + * documents. + */ +#define wbxml_conv_xml2wbxml(a,b,c,d) wbxml_conv_xml2wbxml_withlen(a,WBXML_STRLEN(a),b,c,d) + +/** + * @brief Convert XML to WBXML + * @param xml [in] XML Document to convert + * @param xml_len [in] Length of XML Document + * @param wbxml [out] Resulting WBXML Document + * @param wbxml_len [out] Length of resulting WBXML Document + * @param params [in] Parameters (if NULL, default values are used) + * @return WBXML_OK if conversion succeeded, an Error Code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_conv_xml2wbxml_withlen(WB_UTINY *xml, + WB_ULONG xml_len, + WB_UTINY **wbxml, + WB_ULONG *wbxml_len, + WBXMLGenWBXMLParams *params) LIBWBXML_DEPRECATED; + +/** + * @description This is a container for the WBXML to XML conversion parameters. + * An object style is used because it is much better expandable + * in terms of downward binary compatibility. + */ +typedef struct WBXMLConvWBXML2XML_s WBXMLConvWBXML2XML; + +/** + * @brief Create a new WBXML to XML converter with the default configuration. + * @param conv [out] a reference to the pointer of the new converter + * @return WBXML_OK if conversion succeeded, an Error Code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_conv_wbxml2xml_create(WBXMLConvWBXML2XML **conv); + +/** + * @brief Set the XML generation type (default: WBXML_GEN_XML_INDENT). + * @param conv [in] the converter + * @param gen_type [in] generation type + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_set_gen_type(WBXMLConvWBXML2XML *conv, WBXMLGenXMLType gen_type); + +/** + * @brief Set the used WBXML language. + * The language is usually detected by the specified public ID in the document. + * If the public ID is set then it overrides the language. + * @param conv [in] the converter + * @param lang [in] language (e.g. SYNCML12) + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_set_language(WBXMLConvWBXML2XML *conv, WBXMLLanguage lang); + +/** + * @brief Set the used character set. + * The default character set is UTF-8. + * If the document specifies a character set by it own + * then this character set overrides the parameter charset. + * @param conv [in] the converter + * @param charset [in] the character set + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_set_charset(WBXMLConvWBXML2XML *conv, WBXMLCharsetMIBEnum charset); + +/** + * @brief Set the indent of the generated XML document (please see EXPAT default). + * @param conv [in] the converter + * @param indent [in] the number of blanks + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_set_indent(WBXMLConvWBXML2XML *conv, WB_UTINY indent); + +/** + * @brief Enable whitespace preservation (default: FALSE). + * @param conv [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_enable_preserve_whitespaces(WBXMLConvWBXML2XML *conv); + +/** + * @brief Convert WBXML to XML + * @param conv [in] the converter + * @param wbxml [in] WBXML Document to convert + * @param wbxml_len [in] Length of WBXML Document + * @param xml [out] Resulting XML Document + * @param xml_len [out] XML Document length + * @return WBXML_OK if conversion succeeded, an Error Code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_conv_wbxml2xml_run(WBXMLConvWBXML2XML *conv, + WB_UTINY *xml, + WB_ULONG xml_len, + WB_UTINY **wbxml, + WB_ULONG *wbxml_len); + +/** + * @brief Destroy the converter object. + * @param [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_wbxml2xml_destroy(WBXMLConvWBXML2XML *conv); + +/** + * @description This is a container for the XML to WBXML conversion parameters. + * An object style is used because it is much better expandable + * in terms of downward binary compatibility. + */ +typedef struct WBXMLConvXML2WBXML_s WBXMLConvXML2WBXML; + +/** + * @brief Create a new WBXML to XML converter with the default configuration. + * @param conv [out] a reference to the pointer of the new converter + * @return WBXML_OK if conversion succeeded, an Error Code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_conv_xml2wbxml_create(WBXMLConvXML2WBXML **conv); + +/** + * @brief Set the WBXML version (default: 1.3). + * @param conv [in] the converter + * @param indent [in] the number of blanks + */ +WBXML_DECLARE(void) wbxml_conv_xml2wbxml_set_version(WBXMLConvXML2WBXML *conv, + WBXMLVersion wbxml_version); + +/** + * @brief Enable whitespace preservation (default: FALSE/DISABLED). + * @param conv [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_xml2wbxml_enable_preserve_whitespaces(WBXMLConvXML2WBXML *conv); + +/** + * @brief Disable string table (default: TRUE/ENABLED). + * @param conv [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_xml2wbxml_disable_string_table(WBXMLConvXML2WBXML *conv); + +/** + * @desription: Disable public ID (default: TRUE/ENABLED). + * Usually you don't want to produce WBXML documents which are + * really anonymous. You want a known public ID or a DTD name + * to determine the document type. Some specifications like + * Microsoft's ActiveSync explicitely require fully anonymous + * WBXML documents. If you need this then you must disable + * the public ID mechanism. + * @param conv [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_xml2wbxml_disable_public_id(WBXMLConvXML2WBXML *conv); + +/** + * @brief Convert XML to WBXML + * @param conv [in] the converter + * @param xml [in] XML Document to convert + * @param xml_len [in] Length of XML Document + * @param wbxml [out] Resulting WBXML Document + * @param wbxml_len [out] Length of resulting WBXML Document + * @return WBXML_OK if conversion succeeded, an Error Code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_conv_xml2wbxml_run(WBXMLConvXML2WBXML *conv, + WB_UTINY *xml, + WB_ULONG xml_len, + WB_UTINY **wbxml, + WB_ULONG *wbxml_len); + +/** + * @brief Destroy the converter object. + * @param [in] the converter + */ +WBXML_DECLARE(void) wbxml_conv_xml2wbxml_destroy(WBXMLConvXML2WBXML *conv); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_CONV_H */ diff --git a/src/wbxml_defines.h b/src/wbxml_defines.h new file mode 100644 index 0000000..0ded4e7 --- /dev/null +++ b/src/wbxml_defines.h @@ -0,0 +1,142 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml.h + * @ingroup wbxml + * + * @author Aymerick Jehanne + * @date 02/11/11 + * + * @brief WBXML Library Main Header + */ + +#ifndef WBXML_DEFINES_H +#define WBXML_DEFINES_H + +#if defined( __SYMBIAN32__ ) +/* For basic Symbian Types */ +#include +#endif /* __SYMBIAN32__ */ + +/* + * This sytem includes are here instead of the *.c files because + * we want them to be included AFTER 'e32def.h' on Symbian. If not so, + * a lot of Warnings are displayed ('NULL' : macro redefinition) + */ +#include +#include + + +/** @addtogroup wbxml + * @{ + */ + +/* WBXML Lib basic types redefinition */ +#define WB_BOOL unsigned char +#define WB_UTINY unsigned char +#define WB_TINY char +#define WB_ULONG unsigned int +#define WB_LONG int + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/* Define NULL string */ +#define WBXML_UTINY_NULL_STRING ((WB_UTINY *)"") + +/* WBXML Lib string functions */ +#define WBXML_STRLEN(a) strlen((const WB_TINY*)a) +#define WBXML_STRCMP(a,b) strcmp((const WB_TINY*)a,(const WB_TINY*)b) +#define WBXML_STRNCMP(a,b,c) strncmp((const WB_TINY*)a,(const WB_TINY*)b,c) +#define WBXML_STRSTR(a,b) strstr((const WB_TINY*)a,(const WB_TINY*)b) +#if defined( WIN32 ) +#define WBXML_STRCASECMP(a,b) _stricmp((const WB_TINY*)a,(const WB_TINY*)b) +#define WBXML_STRNCASECMP(a,b,c) _strnicmp((const WB_TINY*)a,(const WB_TINY*)b,c) +#else +#define WBXML_STRCASECMP(a,b) strcasecmp((const WB_TINY*)a,(const WB_TINY*)b) +#define WBXML_STRNCASECMP(a,b,c) strncasecmp((const WB_TINY*)a,(const WB_TINY*)b,c) +#endif /* WIN32 */ + +#define WBXML_ISDIGIT(a) isdigit(a) + +/* For DLL exported functions */ +#if defined( __SYMBIAN32__ ) +#define WBXML_DECLARE(type) EXPORT_C type +#define WBXML_DECLARE_NONSTD(type) EXPORT_C type +#else /* __SYMBIAN32__ */ +#if defined( WIN32 ) +#define WBXML_DECLARE(type) __declspec(dllexport) type __stdcall +#define WBXML_DECLARE_NONSTD(type) __declspec(dllexport) type +#else /* WIN32 */ +#define WBXML_DECLARE(type) type +#define WBXML_DECLARE_NONSTD(type) type +#endif /* WIN32 */ +#endif /* __SYMBIAN32__ */ + +#if __GNUC__ - 0 > 3 || (__GNUC__ - 0 == 3 && __GNUC_MINOR__ - 0 >= 2) + /* gcc >= 3.2 */ +# define LIBWBXML_DEPRECATED __attribute__ ((deprecated)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1300) && (_MSC_VER < 1400) + /* msvc >= 7 */ +# define LIBWBXML_DEPRECATED __declspec(deprecated) +#elif defined(_MSV_VER) && (_MSC_VER >= 1400) + /* MS Visual Studio 2005 */ +# define LIBWBXML_DEPRECATED +#else +# define LIBWBXML_DEPRECATED +#endif + +/** Backward compatibility flag */ +#define WBXML_BACKWARD_COMPAT + +#if defined( WBXML_BACKWARD_COMPAT ) + +/* 0.9.2 */ +#define WBXML_ENCODER_XML_GEN_COMPACT WBXML_GEN_XML_COMPACT +#define WBXML_ENCODER_XML_GEN_INDENT WBXML_GEN_XML_INDENT +#define WBXML_ENCODER_XML_GEN_CANONICAL WBXML_GEN_XML_CANONICAL + +#define WBXMLEncoderXMLGenType WBXMLGenXMLType LIBWBXML_DEPRECATED +#define WBXMLConvWBXML2XMLParams WBXMLGenXMLParams LIBWBXML_DEPRECATED +#define WBXMLConvXML2WBXMLParams WBXMLGenWBXMLParams LIBWBXML_DEPRECATED + +// #define WBXMLTag WBXMLTagName +// #define WBXMLTagEntry WBXMLTagNameEntry + +#endif /* WBXML_BACKWARD_COMPAT */ + +/** @} */ + +#endif /* WBXML_DEFINES_H */ diff --git a/src/wbxml_elt.c b/src/wbxml_elt.c new file mode 100644 index 0000000..28dafd6 --- /dev/null +++ b/src/wbxml_elt.c @@ -0,0 +1,332 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_elt.c + * @ingroup wbxml_elt + * + * @author Aymerick Jehanne + * @date 03/02/22 + * + * @brief WBXML Elements + */ + +#include "wbxml_elt.h" + + +/** For an unknown XML Name */ +#define WBXML_ELT_UNKNOWN_NAME ((WB_UTINY *)"unknown") + + + +/*************************************************** + * Public Functions + */ + +/* WBXMLTag */ + +WBXML_DECLARE(WBXMLTag *) wbxml_tag_create(WBXMLValueType type) +{ + WBXMLTag *result = NULL; + + if ((result = (WBXMLTag *) wbxml_malloc(sizeof(WBXMLTag))) == NULL) + return NULL; + + result->type = type; + result->u.token = NULL; + result->u.literal = NULL; + + return result; +} + + +WBXML_DECLARE(WBXMLTag *) wbxml_tag_create_token(const WBXMLTagEntry *value) +{ + WBXMLTag *result = NULL; + + if ((result = wbxml_tag_create(WBXML_VALUE_TOKEN)) == NULL) + return NULL; + + result->u.token = value; + + return result; +} + + +WBXML_DECLARE(WBXMLTag *) wbxml_tag_create_literal(WB_UTINY *value) +{ + WBXMLTag *result = NULL; + + if ((result = wbxml_tag_create(WBXML_VALUE_LITERAL)) == NULL) + return NULL; + + if (value == NULL) + result->u.literal = NULL; + else { + result->u.literal = wbxml_buffer_create(value, WBXML_STRLEN(value), WBXML_STRLEN(value)); + if (result->u.literal == NULL) { + wbxml_tag_destroy(result); + return NULL; + } + } + + return result; +} + + +WBXML_DECLARE(void) wbxml_tag_destroy(WBXMLTag *tag) +{ + if (tag == NULL) + return; + + if (tag->type == WBXML_VALUE_LITERAL) + wbxml_buffer_destroy(tag->u.literal); + + wbxml_free(tag); +} + + +WBXML_DECLARE(WBXMLTag *) wbxml_tag_duplicate(WBXMLTag *tag) +{ + WBXMLTag *result = NULL; + + if (tag == NULL) + return NULL; + + if ((result = (WBXMLTag *) wbxml_malloc(sizeof(WBXMLTag))) == NULL) + return NULL; + + result->type = tag->type; + + switch (result->type) { + case WBXML_VALUE_TOKEN: + result->u.token = tag->u.token; + break; + case WBXML_VALUE_LITERAL: + result->u.literal = wbxml_buffer_duplicate(tag->u.literal); + break; + default: + /* Must Never Happen ! */ + wbxml_free(result); + return NULL; + } + + return result; +} + + +WBXML_DECLARE(const WB_UTINY *) wbxml_tag_get_xml_name(WBXMLTag *tag) +{ + if (tag == NULL) + return WBXML_ELT_UNKNOWN_NAME; + + switch (tag->type) { + case WBXML_VALUE_TOKEN: + return (const WB_UTINY *) tag->u.token->xmlName; + break; + case WBXML_VALUE_LITERAL: + return (const WB_UTINY *) wbxml_buffer_get_cstr(tag->u.literal); + default: + return WBXML_ELT_UNKNOWN_NAME; + } +} + + +/* WBXMLAttributeName */ + +WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_create(WBXMLValueType type) +{ + WBXMLAttributeName *result = NULL; + + if ((result = (WBXMLAttributeName *) wbxml_malloc(sizeof(WBXMLAttributeName))) == NULL) + return NULL; + + result->type = type; + result->u.token = NULL; + result->u.literal = NULL; + + return result; +} + + +WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_create_token(const WBXMLAttrEntry *value) +{ + WBXMLAttributeName *result = NULL; + + if ((result = wbxml_attribute_name_create(WBXML_VALUE_TOKEN)) == NULL) + return NULL; + + result->u.token = value; + + return result; +} + + +WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_create_literal(WB_UTINY *value) +{ + WBXMLAttributeName *result = NULL; + + if ((result = wbxml_attribute_name_create(WBXML_VALUE_LITERAL)) == NULL) + return NULL; + + if (value == NULL) + result->u.literal = NULL; + else { + result->u.literal = wbxml_buffer_create(value, WBXML_STRLEN(value), WBXML_STRLEN(value)); + if (result->u.literal == NULL) { + wbxml_attribute_name_destroy(result); + return NULL; + } + } + + return result; +} + + +WBXML_DECLARE(void) wbxml_attribute_name_destroy(WBXMLAttributeName *name) +{ + if (name == NULL) + return; + + if (name->type == WBXML_VALUE_LITERAL) + wbxml_buffer_destroy(name->u.literal); + + wbxml_free(name); +} + + +WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_duplicate(WBXMLAttributeName *name) +{ + WBXMLAttributeName *result = NULL; + + if (name == NULL) + return NULL; + + if ((result = (WBXMLAttributeName *) wbxml_malloc(sizeof(WBXMLAttributeName))) == NULL) + return NULL; + + result->type = name->type; + + switch (result->type) { + case WBXML_VALUE_TOKEN: + result->u.token = name->u.token; + break; + case WBXML_VALUE_LITERAL: + result->u.literal = wbxml_buffer_duplicate(name->u.literal); + break; + default: + /* Must Never Happen ! */ + wbxml_free(result); + return NULL; + } + + return result; +} + + +WBXML_DECLARE(const WB_UTINY *) wbxml_attribute_name_get_xml_name(WBXMLAttributeName *name) +{ + if (name == NULL) + return WBXML_ELT_UNKNOWN_NAME; + + switch (name->type) { + case WBXML_VALUE_TOKEN: + return (const WB_UTINY *) name->u.token->xmlName; + break; + case WBXML_VALUE_LITERAL: + return (const WB_UTINY *) wbxml_buffer_get_cstr(name->u.literal); + default: + return WBXML_ELT_UNKNOWN_NAME; + } +} + + +/* WBXMLAttribute */ + +WBXML_DECLARE(WBXMLAttribute *) wbxml_attribute_create(void) +{ + WBXMLAttribute *result = NULL; + + if ((result = (WBXMLAttribute *) wbxml_malloc(sizeof(WBXMLAttribute))) == NULL) + return NULL; + + result->name = NULL; + result->value = NULL; + + return result; +} + + +WBXML_DECLARE(void) wbxml_attribute_destroy(WBXMLAttribute *attr) +{ + if (attr == NULL) + return; + + wbxml_attribute_name_destroy(attr->name); + wbxml_buffer_destroy(attr->value); + + wbxml_free(attr); +} + + +WBXML_DECLARE_NONSTD(void) wbxml_attribute_destroy_item(void *attr) +{ + wbxml_attribute_destroy((WBXMLAttribute *) attr); +} + + +WBXML_DECLARE(WBXMLAttribute *) wbxml_attribute_duplicate(WBXMLAttribute *attr) +{ + WBXMLAttribute *result = NULL; + + if (attr == NULL) + return NULL; + + if ((result = (WBXMLAttribute *) wbxml_malloc(sizeof(WBXMLAttribute))) == NULL) + return NULL; + + result->name = wbxml_attribute_name_duplicate(attr->name); + result->value = wbxml_buffer_duplicate(attr->value); + + return result; +} + + +WBXML_DECLARE(const WB_UTINY *) wbxml_attribute_get_xml_name(WBXMLAttribute *attr) +{ + if (attr == NULL) + return WBXML_ELT_UNKNOWN_NAME; + + return wbxml_attribute_name_get_xml_name(attr->name); +} + + +WBXML_DECLARE(const WB_UTINY *) wbxml_attribute_get_xml_value(WBXMLAttribute *attr) +{ + if ((attr == NULL) || (attr->value == NULL)) + return WBXML_UTINY_NULL_STRING; + + return wbxml_buffer_get_cstr(attr->value); +} diff --git a/src/wbxml_elt.h b/src/wbxml_elt.h new file mode 100644 index 0000000..a31c4d3 --- /dev/null +++ b/src/wbxml_elt.h @@ -0,0 +1,241 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_elt.h + * @ingroup wbxml_elt + * + * @author Aymerick Jehanne + * @date 03/02/22 + * + * @brief WBXML Elements + */ + +#ifndef WBXML_ELT_H +#define WBXML_ELT_H + +#include "wbxml.h" +#include "wbxml_buffers.h" +#include "wbxml_tables.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_elt + * @{ + */ + +/** + * @brief WBXML Value Type + */ +typedef enum WBXMLValueType_e { + WBXML_VALUE_TOKEN = 0, /**< WBXML Token value */ + WBXML_VALUE_LITERAL /**< WBXML Literal value */ +} WBXMLValueType; + + +/** @brief WBXML Tag structure */ +typedef struct WBXMLTag_s { + WBXMLValueType type; /**< Tag Type (Token or Literal) */ + union { + const WBXMLTagEntry *token; /**< Token Tag (MUST be const structure, ie from wbxml_tables.c) */ + WBXMLBuffer *literal; /**< Literal Tag (MUST be dynamically allocated WBXMLBuffer) */ + } u; +} WBXMLTag; + + +/** @brief WBXML Attribute Name structure */ +typedef struct WBXMLAttributeName_s { + WBXMLValueType type; /**< Attribute Name Type (Token or Literal) */ + union { + const WBXMLAttrEntry *token; /**< Token Attribute Name (MUST be const structure, ie from wbxml_tables.c) */ + WBXMLBuffer *literal; /**< Literal Attribute Name (MUST be dynamically allocated WBXMLBuffer) */ + } u; +} WBXMLAttributeName; + + +/** + * @brief WBXML Attribute structure + * @note The 'value' part contain the FULL attribute value + * For example, with the attribute: url="http://127.0.0.1/" + * If the 'name' part is this: + * - name->u.token->wbxmlCodePage: 0x00 + * - name->u.token->wbxmlToken : 0x4b + * - name->u.token->xmlName : "url" + * - name->u.token->xmlValue: "http://" + * + * Then, 'value' is still: "http://127.0.0.1/" + * + * Of course (in this example) it should be better to have the wbxmlToken 0x4a ("url" / NULL). So you mustn't take into + * account the 'xmlValue' field for 'name' to get the Attribute Value of this Attribute. + */ +typedef struct WBXMLAttribute_s { + WBXMLAttributeName *name; /**< Attribute Name */ + WBXMLBuffer *value; /**< Full Attribute Value */ +} WBXMLAttribute; + + +/**************************************************** + * WBXML Elt Functions + */ + +/* WBXMLTag */ + +/** + * @brief Create a Tag structure + * @param type WBXML Value Type + * @return The newly created Tag, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLTag *) wbxml_tag_create(WBXMLValueType type); + +/** + * @brief Additional function to create directly a Token Tag structure + * @param value The WBXMLTagEntry value + * @return The newly created Tag, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLTag *) wbxml_tag_create_token(const WBXMLTagEntry *value); + +/** + * @brief Additional function to create directly a Literal Tag structure + * @param value The Literal value + * @return The newly created Tag, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLTag *) wbxml_tag_create_literal(WB_UTINY *value); + +/** + * @brief Destroy a Tag structure + * @param tag The Tag structure to destroy + */ +WBXML_DECLARE(void) wbxml_tag_destroy(WBXMLTag *tag); + +/** + * @brief Duplicate a Tag structure + * @param tag The Tag structure to duplicate + * @return The duplicated Tag structure, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLTag *) wbxml_tag_duplicate(WBXMLTag *tag); + +/** + * @brief Get the XML Name of a WBXML Tag + * @param tag The WBXML Tag + * @return The XML Name, or "unknown" if not found + */ +WBXML_DECLARE(const WB_UTINY *) wbxml_tag_get_xml_name(WBXMLTag *tag); + + +/* WBXMLAttributeName */ + +/** + * @brief Create an Attribute Name structure + * @param type WBXML Value Type + * @return The newly created Attribute Name, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_create(WBXMLValueType type); + +/** + * @brief Additional function to create directly a Token Attribute Name structure + * @param value The WBXMLTagEntry value + * @return The newly created Attribute Name, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_create_token(const WBXMLAttrEntry *value); + +/** + * @brief Additional function to create directly a Literal Attribute Name structure + * @param value The Literal value + * @return The newly created Attribute Name, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_create_literal(WB_UTINY *value); + +/** + * @brief Destroy an Attribute Name structure + * @param name The Attribute Name structure to destroy + */ +WBXML_DECLARE(void) wbxml_attribute_name_destroy(WBXMLAttributeName *name); + +/** + * @brief Duplicate a Attribute Name structure + * @param name The Attribute Name structure to duplicate + * @return The duplicated Attribute Name structure, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLAttributeName *) wbxml_attribute_name_duplicate(WBXMLAttributeName *name); + +/** + * @brief Get the XML Name of a WBXML Attribute Name + * @param name The WBXML Attribute Name + * @return The XML Name, or "unknown" if not found + */ +WBXML_DECLARE(const WB_UTINY *) wbxml_attribute_name_get_xml_name(WBXMLAttributeName *name); + + +/* WBXMLAttribute */ + +/** + * @brief Create an Attribute structure + * @return The newly created Attribute, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLAttribute *) wbxml_attribute_create(void); + +/** + * @brief Destroy an Attribute structure + * @param attr The Attribute structure to destroy + */ +WBXML_DECLARE(void) wbxml_attribute_destroy(WBXMLAttribute *attr); + +/** + * @brief Destroy an Attribute structure (used for wbxml_list_destroy()) + * @param attr The Attribute structure to destroy + */ +WBXML_DECLARE_NONSTD(void) wbxml_attribute_destroy_item(void *attr); + +/** + * @brief Duplicate an Attribute structure + * @param attr The Attribute structure to duplicate + * @return The duplicated Attribute, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLAttribute *) wbxml_attribute_duplicate(WBXMLAttribute *attr); + +/** + * @brief Get the XML Attribute Name of a WBXML Attribute + * @param attr The WBXML Attribute + * @return The XML Attribute Name, or "unknown" if not found + */ +WBXML_DECLARE(const WB_UTINY *) wbxml_attribute_get_xml_name(WBXMLAttribute *attr); + +/** + * @brief Get the XML Attribute Value of a WBXML Attribute + * @param attr The WBXML Attribute + * @return The XML Attribute Value, or "" if none + */ +WBXML_DECLARE(const WB_UTINY *) wbxml_attribute_get_xml_value(WBXMLAttribute *attr); + + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_ELT_H */ diff --git a/src/wbxml_encoder.c b/src/wbxml_encoder.c new file mode 100644 index 0000000..2eb9be6 --- /dev/null +++ b/src/wbxml_encoder.c @@ -0,0 +1,4631 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2008-2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_encoder.c + * @ingroup wbxml_encoder + * + * @author Aymerick Jehanne + * @date 11/11/02 + * + * @brief WBXML Encoder - Encodes a WBXML Tree to WBXML or to XML + * + * @note Inspired from kannel WML Encoder (http://www.kannel.org) + * + * @note [OMA WV 1.1] : OMA-WV-CSP_WBXML-V1_1-20021001-A.pdf + * + * @todo Parse CDDATA + * @todo Parse PI + * @todo Handle Charsets Encoding + * @todo Really generate ENTITY tokens + * @todo Handle Namespaces ! + * @todo For canonical XML output: Sort the Attributes + * @todo When adding string to String Table, check that this is not a Content Text that will be tokenized + * @todo For Wireless-Village CSP : + * - Encode "Date and Time" in OPAQUE (OMA-WV-CSP_WBXML-V1_1-20021001-A.pdf - 6.6) + * + * @todo Review the canonical XML generation: + * - http://www.jclark.com/xml/canonxml.html +* - http://www.w3.org/TR/2004/REC-xml-20040204/ + */ + +#include /* For isdigit() */ + +#include "wbxml_encoder.h" +#include "wbxml_log.h" +#include "wbxml_internals.h" +#include "wbxml_base64.h" + + +/** + * Compilation Flag: WBXML_ENCODER_USE_STRTBL + * ----------------- + * Do We Use String Table when Encoding to WBXML ? + * (NOTE: We still use String Table for Unknown Public ID, even if this flag is not set) + */ + +/* WBXML Header: version publicid charset length + * u_int8 mb_u_int32 mb_u_int32 mb_u_int32 + * 1 octet 5 octets 5 octets 5 octets : 16 octets + * mb_u_int32: 5 octets (to handle continuation bits) + */ +#define WBXML_HEADER_MAX_LEN 16 + +/* Memory management related defines */ +#define WBXML_ENCODER_XML_DOC_MALLOC_BLOCK 5000 +#define WBXML_ENCODER_WBXML_DOC_MALLOC_BLOCK 1000 + +#define WBXML_ENCODER_XML_HEADER_MALLOC_BLOCK 250 +#define WBXML_ENCODER_WBXML_HEADER_MALLOC_BLOCK WBXML_HEADER_MAX_LEN + +/* WBXML Default Charset: UTF-8 (106) */ +#define WBXML_ENCODER_DEFAULT_CHARSET 0x6a + +/* String Terminating NULL Char */ +#define WBXML_STR_END '\0' + +/* Minimum String Size needed for String Table - @note Set to '3' for Prov 1.0 */ +#define WBXML_ENCODER_STRING_TABLE_MIN 3 + +/** + * Default charset of the outputed WBXML document. Used only in this case : + * - No charset was indicated thanks to the function 'wbxml_encoder_set_output_charset()' + * - and the WBXML Tree field 'orig_charset' is set to WBXML_CHARSET_UNKNOWN (ie. charset + * information not found in original document) + */ +#define WBXML_ENCODER_WBXML_DEFAULT_CHARSET WBXML_CHARSET_UTF_8 + +/** + * Default charset of the outputed XML document. Used only in this case : + * - No charset was indicated thanks to the function 'wbxml_encoder_set_output_charset()' + * - and the WBXML Tree field 'orig_charset' is set to WBXML_CHARSET_UNKNOWN (ie. charset + * information not found in original document) + */ +#define WBXML_ENCODER_XML_DEFAULT_CHARSET WBXML_CHARSET_UTF_8 + +/** + * If defined, generate empty XML elements (eg: <foo />), else generate + * full "end element" (eg: <foo></foo>) + * + * @todo This must be a 'WBXMLGenXMLParams' parameter + */ +#define WBXML_ENCODER_XML_GEN_EMPTY_ELT + +/** + * If defined, do not indent elements that have no element child (eg: <foo>bar</foo>), + * else indent anyway (eg: <foo> + * bar + * </foo>) + * + * @todo This must be a 'WBXMLGenXMLParams' parameter + */ +#define WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT + + +/** + * @warning For now 'current_tag' field is only used for WV Content Encoding. And for this use, it works. + * But this field is reset after End Tag, and as there is no Linked List mecanism, this is bad for + * cascading elements: we don't fill this field with parent Tag when parsing End Tag. + * + * @warning For now 'current_text_parent' field is only used for DRM REL Content Encoding. It should not be + * used for another purpose. + * + * @warning For now 'current_node' field is a hack. It is reset after End Tag, and as there is no Linked List + * mecanism, this is bad for cascading elements: we don't fill this field with parent Tag + * when parsing End Tag. + */ +struct WBXMLEncoder_s { + WBXMLTree *tree; /**< WBXML Tree to Encode */ + const WBXMLLangEntry *lang; /**< Language table to use */ + WBXMLBuffer *output; /**< The output (wbxml or xml) we are producing */ + WBXMLBuffer *output_header; /**< The output header (used if Flow Mode encoding is activated) */ + const WBXMLTagEntry *current_tag; /**< Current Tag (See The Warning For This Field !) */ + const WBXMLTreeNode *current_text_parent; /**< Text parent of current Node (See The Warning For This Field !) */ + const WBXMLAttrEntry *current_attr; /**< Current Attribute */ + WBXMLTreeNode *current_node; /**< Current Node (See The Warning For This Field !) */ + WB_UTINY tagCodePage; /**< Current Tag Code Page */ + WB_UTINY attrCodePage; /**< Current Attribute Code Page */ + WB_BOOL ignore_empty_text; /**< Do we ignore empty text nodes (ie: ignorable whitespaces)? */ + WB_BOOL remove_text_blanks; /**< Do we remove leading and trailing blanks in text nodes ? */ + WBXMLEncoderOutputType output_type; /**< Output Type */ + WBXMLGenXMLType xml_gen_type; /**< XML Generation Type */ + WB_UTINY indent_delta; /**< Indent Delta (number of spaces) */ + WB_UTINY indent; /**< Current Indent */ + WB_BOOL in_content; /**< We are in Content Text (used for indentation when generating XML output) */ + WB_BOOL in_cdata; /**< We are in a CDATA section (and so, content must be generaed "as is") */ + WBXMLBuffer *cdata; /**< Current CDATA Buffer */ +#if defined( WBXML_ENCODER_USE_STRTBL ) + WBXMLList *strstbl; /**< String Table we are creating */ + WB_ULONG strstbl_len; /**< String Table Length */ + WB_BOOL use_strtbl; /**< Do we use String Table when generating WBXML output ? (default: YES) */ +#endif /* WBXML_ENCODER_USE_STRTBL */ + WB_BOOL xml_encode_header; /**< Do we generate XML Header ? */ + WB_BOOL produce_anonymous; /**< Do we produce anonymous documents? (default: NO) */ + WBXMLVersion wbxml_version; /**< WBXML Version to use (when generating WBXML output) */ + WBXMLCharsetMIBEnum output_charset; /**< Output charset encoding */ + WB_BOOL flow_mode; /**< Is Flow Mode encoding activated ? */ + WB_ULONG pre_last_node_len; /**< Output buffer length before last node encoding */ + WB_BOOL textual_publicid; /**< Generate textual Public ID instead of token (when generating WBXML output) */ +}; + +#if defined( WBXML_ENCODER_USE_STRTBL ) +/** + * @brief The WBXML String Table Element + */ +typedef struct WBXMLStringTableElement_t { + WBXMLBuffer *string; /**< String */ + WB_ULONG offset; /**< Offset of String in String Table */ + WB_ULONG count; /**< Number of times this String is referenced in the XML Document */ + WB_BOOL stat; /**< If set to TRUE, this is a static String that we must not destroy in wbxml_strtbl_element_destroy() function */ +} WBXMLStringTableElement; +#endif /* WBXML_ENCODER_USE_STRTBL */ + +/** + * @brief WBXML Value Element Context: In Content or in Attribute Value + */ +typedef enum WBXMLValueElementCtx_e { + WBXML_VALUE_ELEMENT_CTX_CONTENT = 0, /**< Text Content */ + WBXML_VALUE_ELEMENT_CTX_ATTR /**< Attribute Value */ +} WBXMLValueElementCtx; + +/** + * @brief WBXML Value Element Type: string / tableref / extension / opaque + */ +typedef enum WBXMLValueElementType_e { + WBXML_VALUE_ELEMENT_STRING = 0, /**< Inline String */ + WBXML_VALUE_ELEMENT_EXTENSION, /**< Extension Token */ + WBXML_VALUE_ELEMENT_OPAQUE, /**< Opaque Buffer */ + WBXML_VALUE_ELEMENT_ATTR_TOKEN /**< Attribute Value Token */ +#if defined( WBXML_ENCODER_USE_STRTBL ) + , WBXML_VALUE_ELEMENT_TABLEREF /**< String Table Reference */ +#endif /* WBXML_ENCODER_USE_STRTBL */ +} WBXMLValueElementType; + +/** + * @brief WBXML Value Element Structure + */ +typedef struct WBXMLValueElement_t { + WBXMLValueElementType type; /**< Cf WBXMLValueElementType enum */ + union { + WBXMLBuffer *str; /**< WBXML_VALUE_ELEMENT_STRING */ + const WBXMLExtValueEntry *ext; /**< WBXML_VALUE_ELEMENT_EXTENSION */ + WBXMLBuffer *buff; /**< WBXML_VALUE_ELEMENT_OPAQUE */ + const WBXMLAttrValueEntry *attr; /**< WBXML_VALUE_ELEMENT_ATTR_TOKEN */ +#if defined( WBXML_ENCODER_USE_STRTBL ) + WB_ULONG index; /**< WBXML_VALUE_ELEMENT_TABLEREF */ +#endif /* WBXML_ENCODER_USE_STRTBL */ + } u; +} WBXMLValueElement; + + +/*************************************************** + * Private Functions prototypes + */ + +/******************************* + * Common Functions + */ + +#if 0 +static WB_BOOL convert_char_to_ucs4(WB_UTINY ch, WB_ULONG *result); +#endif /* 0 */ + +static WBXMLEncoder *encoder_duplicate(WBXMLEncoder *encoder); +static WBXMLError encoder_encode_tree(WBXMLEncoder *encoder); +static WB_BOOL encoder_init_output(WBXMLEncoder *encoder); + + +/******************************* + * WBXML Tree Parsing Functions + */ + +static WBXMLError parse_node(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL enc_end); +static WBXMLError parse_element(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content); +static WBXMLError parse_element_end(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content); +static WBXMLError parse_attribute(WBXMLEncoder *encoder, WBXMLAttribute *attribute); +static WBXMLError parse_text(WBXMLEncoder *encoder, WBXMLTreeNode *node); +static WBXMLError parse_cdata(WBXMLEncoder *encoder); +static WBXMLError parse_pi(WBXMLEncoder *encoder, WBXMLTreeNode *node); +static WBXMLError parse_tree(WBXMLEncoder *encoder, WBXMLTreeNode *node); + + +/******************************* + * WBXML Output Functions + */ + +/* Build WBXML Result */ +static WBXMLError wbxml_build_result(WBXMLEncoder *encoder, WB_UTINY **wbxml, WB_ULONG *wbxml_len); +static WBXMLError wbxml_fill_header(WBXMLEncoder *encoder, WBXMLBuffer *header); + +/* WBXML Encoding Functions */ +static WBXMLError wbxml_encode_end(WBXMLEncoder *encoder); + +static WBXMLError wbxml_encode_tag(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content); +static WBXMLError wbxml_encode_tag_literal(WBXMLEncoder *encoder, const WB_UTINY *tag, WB_UTINY mask); +static WBXMLError wbxml_encode_tag_token(WBXMLEncoder *encoder, WB_UTINY token, WB_UTINY page); + +static WBXMLError wbxml_encode_attr(WBXMLEncoder *encoder, WBXMLAttribute *attribute); +static WBXMLError wbxml_encode_attr_start(WBXMLEncoder *encoder, WBXMLAttribute *attribute, WB_UTINY **value); +static WBXMLError wbxml_encode_value_element_buffer(WBXMLEncoder *encoder, WB_UTINY *value, WBXMLValueElementCtx ctx); +static WBXMLError wbxml_encode_value_element_list(WBXMLEncoder *encoder, WBXMLList *list); +static WBXMLError wbxml_encode_attr_start_literal(WBXMLEncoder *encoder, const WB_UTINY *attr); +static WBXMLError wbxml_encode_attr_token(WBXMLEncoder *encoder, WB_UTINY token, WB_UTINY page); + +static WBXMLError wbxml_encode_inline_string(WBXMLEncoder *encoder, WBXMLBuffer *str); +static WBXMLError wbxml_encode_inline_integer_extension_token(WBXMLEncoder *encoder, WB_UTINY ext, WB_UTINY value); +#if 0 +static WBXMLError wbxml_encode_entity(WBXMLEncoder *encoder, WB_ULONG value); +#endif /* 0 */ +static WBXMLError wbxml_encode_opaque(WBXMLEncoder *encoder, WBXMLBuffer *buff); +static WBXMLError wbxml_encode_opaque_data(WBXMLEncoder *encoder, WB_UTINY *data, WB_ULONG data_len); +#if defined( WBXML_ENCODER_USE_STRTBL ) +static WBXMLError wbxml_encode_tableref(WBXMLEncoder *encoder, WB_ULONG offset); +#endif /* WBXML_ENCODER_USE_STRTBL */ + +static WBXMLValueElement *wbxml_value_element_create(void); +static void wbxml_value_element_destroy(WBXMLValueElement *elt); +static void wbxml_value_element_destroy_item(void *elt); + +static WBXMLError wbxml_encode_tree(WBXMLEncoder *encoder, WBXMLTree *tree); + +#if ( defined( WBXML_SUPPORT_SI ) || defined( WBXML_SUPPORT_EMN ) ) +static WBXMLError wbxml_encode_datetime(WBXMLEncoder *encoder, WB_UTINY *buffer); +#endif /* WBXML_SUPPORT_SI || WBXML_SUPPORT_EMN */ + +#if defined( WBXML_SUPPORT_WV ) +static WBXMLError wbxml_encode_wv_content(WBXMLEncoder *encoder, WB_UTINY *buffer); +static WBXMLError wbxml_encode_wv_integer(WBXMLEncoder *encoder, WB_UTINY *buffer); +static WBXMLError wbxml_encode_wv_datetime(WBXMLEncoder *encoder, WB_UTINY *buffer); +#endif /* WBXML_SUPPORT_WV */ + +#if defined( WBXML_SUPPORT_DRMREL ) +static WBXMLError wbxml_encode_drmrel_content(WBXMLEncoder *encoder, WB_UTINY *buffer); +#endif /* WBXML_SUPPORT_DRMREL */ + +#if defined( WBXML_SUPPORT_OTA_SETTINGS ) +static WBXMLError wbxml_encode_ota_nokia_icon(WBXMLEncoder *encoder, WB_UTINY *buffer); +#endif /* WBXML_SUPPORT_OTA_SETTINGS */ + +#if defined( WBXML_ENCODER_USE_STRTBL ) +/* WBXML String Table Functions */ +static WBXMLStringTableElement *wbxml_strtbl_element_create(WBXMLBuffer *string, WB_BOOL is_stat); +static void wbxml_strtbl_element_destroy(WBXMLStringTableElement *element); +static void wbxml_strtbl_element_destroy_item(void *element); + +static WBXMLError wbxml_strtbl_initialize(WBXMLEncoder *encoder, WBXMLTreeNode *root); +static void wbxml_strtbl_collect_strings(WBXMLEncoder *encoder, WBXMLTreeNode *node, WBXMLList *strings); +static WBXMLError wbxml_strtbl_collect_words(WBXMLList *elements, WBXMLList **result); +static WBXMLError wbxml_strtbl_construct(WBXMLBuffer *buff, WBXMLList *strstbl); +static WBXMLError wbxml_strtbl_check_references(WBXMLEncoder *encoder, WBXMLList **strings, WBXMLList **one_ref, WB_BOOL stat_buff); +static WB_BOOL wbxml_strtbl_add_element(WBXMLEncoder *encoder, WBXMLStringTableElement *elt, WB_ULONG *index, WB_BOOL *added); +#endif /* WBXML_ENCODER_USE_STRTBL */ + + +/******************************* + * XML Output Functions + */ + +/** New Line */ +#define WBXML_ENCODER_XML_NEW_LINE ((WB_UTINY *)"\n") + +/* XML Header Macros */ +#define WBXML_ENCODER_XML_HEADER "" +#define WBXML_ENCODER_XML_DOCTYPE "" + +/* Global vars for XML Normalization */ +const WB_UTINY xml_lt[5] = "<"; /**< < */ +const WB_UTINY xml_gt[5] = ">"; /**< > */ +const WB_UTINY xml_amp[6] = "&"; /**< & */ +const WB_UTINY xml_quot[7] = """; /**< " */ +const WB_UTINY xml_apos[7] = "'"; /**< ' */ +const WB_UTINY xml_slashr[6] = " "; /**< */ +const WB_UTINY xml_slashn[6] = " "; /**< */ +const WB_UTINY xml_tab[5] = " "; /**< */ + +/* Build XML Result */ +static WBXMLError xml_build_result(WBXMLEncoder *encoder, WB_UTINY **xml, WB_ULONG *xml_len); +static WBXMLError xml_fill_header(WBXMLEncoder *encoder, WBXMLBuffer *header); + +/* XML Encoding Functions */ +static WBXMLError xml_encode_tag(WBXMLEncoder *encoer, WBXMLTreeNode *node); +static WBXMLError xml_encode_end_tag(WBXMLEncoder *encoder, WBXMLTreeNode *node); + +static WBXMLError xml_encode_attr(WBXMLEncoder *encoder, WBXMLAttribute *attribute); +static WBXMLError xml_encode_end_attrs(WBXMLEncoder *encoder, WBXMLTreeNode *node); + +static WBXMLError xml_encode_text(WBXMLEncoder *encoder, WBXMLTreeNode *node); +static WBXMLError xml_encode_text_entities(WBXMLEncoder *encoder, WBXMLBuffer *buff); +static WB_BOOL xml_encode_new_line(WBXMLBuffer *buff); + +static WBXMLError xml_encode_cdata(WBXMLEncoder *encoder); +static WBXMLError xml_encode_end_cdata(WBXMLEncoder *encoder); + +static WBXMLError xml_encode_tree(WBXMLEncoder *encoder, WBXMLTree *tree); + + +/*************************************************** + * Public Functions + */ + +WBXML_DECLARE(WBXMLEncoder *) wbxml_encoder_create_real(void) +{ + WBXMLEncoder *encoder = NULL; + + encoder = (WBXMLEncoder *) wbxml_malloc(sizeof(WBXMLEncoder)); + if (encoder == NULL) { + return NULL; + } + +#if defined( WBXML_ENCODER_USE_STRTBL ) + if ((encoder->strstbl = wbxml_list_create()) == NULL) { + wbxml_free(encoder); + return NULL; + } + encoder->use_strtbl = TRUE; + encoder->strstbl_len = 0; +#endif /* WBXML_ENCODER_USE_STRTBL */ + + encoder->tree = NULL; + encoder->lang = NULL; + encoder->output = NULL; + encoder->output_header = NULL; + + encoder->current_tag = NULL; + encoder->current_text_parent = NULL; + encoder->current_attr = NULL; + encoder->current_node = NULL; + + encoder->tagCodePage = 0; + encoder->attrCodePage = 0; + + encoder->ignore_empty_text = FALSE; + encoder->remove_text_blanks = FALSE; + + encoder->output_type = WBXML_ENCODER_OUTPUT_WBXML; + encoder->xml_gen_type = WBXML_GEN_XML_COMPACT; + + encoder->indent_delta = 1; + encoder->indent = 0; + encoder->in_content = FALSE; + encoder->in_cdata = FALSE; + encoder->cdata = NULL; + + encoder->xml_encode_header = TRUE; + encoder->produce_anonymous = FALSE; + + /* Default Version: WBXML 1.3 */ + encoder->wbxml_version = WBXML_VERSION_13; + + /** + * Default Output Charset Encoding is the one found in WBXML Tree, + * so set it as 'unknown' for now. + */ + encoder->output_charset = WBXML_CHARSET_UNKNOWN; + + encoder->flow_mode = FALSE; + encoder->pre_last_node_len = 0; + encoder->textual_publicid = FALSE; + + return encoder; +} + + +WBXML_DECLARE(void) wbxml_encoder_destroy(WBXMLEncoder *encoder) +{ + if (encoder == NULL) + return; + + wbxml_buffer_destroy(encoder->output); + wbxml_buffer_destroy(encoder->output_header); + wbxml_buffer_destroy(encoder->cdata); + +#if defined( WBXML_ENCODER_USE_STRTBL ) + wbxml_list_destroy(encoder->strstbl, wbxml_strtbl_element_destroy_item); +#endif /* WBXML_ENCODER_USE_STRTBL */ + + wbxml_free(encoder); +} + + +WBXML_DECLARE(void) wbxml_encoder_reset(WBXMLEncoder *encoder) +{ + if (encoder == NULL) + return; + + encoder->tree = NULL; + + wbxml_buffer_destroy(encoder->output); + encoder->output = NULL; + + wbxml_buffer_destroy(encoder->output_header); + encoder->output_header = NULL; + + encoder->current_tag = NULL; + encoder->current_attr = NULL; + encoder->current_node = NULL; + + encoder->tagCodePage = 0; + encoder->attrCodePage = 0; + + encoder->in_content = FALSE; + encoder->in_cdata = FALSE; + + wbxml_buffer_destroy(encoder->cdata); + encoder->cdata = NULL; + + encoder->pre_last_node_len = 0; + +#if defined( WBXML_ENCODER_USE_STRTBL ) + wbxml_list_destroy(encoder->strstbl, wbxml_strtbl_element_destroy_item); + encoder->strstbl = NULL; + encoder->strstbl_len = 0; +#endif /* WBXML_ENCODER_USE_STRTBL */ +} + + +WBXML_DECLARE(void) wbxml_encoder_set_ignore_empty_text(WBXMLEncoder *encoder, WB_BOOL set_ignore) +{ + if (encoder == NULL) + return; + + encoder->ignore_empty_text = set_ignore; +} + + +WBXML_DECLARE(void) wbxml_encoder_set_remove_text_blanks(WBXMLEncoder *encoder, WB_BOOL set_remove) +{ + if (encoder == NULL) + return; + + encoder->remove_text_blanks = set_remove; +} + + +WBXML_DECLARE(void) wbxml_encoder_set_output_charset(WBXMLEncoder *encoder, WBXMLCharsetMIBEnum charset) +{ + if (encoder == NULL) + return; + + /* Tell which Output Charset Encoding to use (this overides the Charset Encoding found in WBXML Tree) */ + encoder->output_charset = charset; +} + + +WBXML_DECLARE(void) wbxml_encoder_set_use_strtbl(WBXMLEncoder *encoder, WB_BOOL use_strtbl) +{ +#if defined( WBXML_ENCODER_USE_STRTBL ) + if (encoder == NULL) + return; + + encoder->use_strtbl = use_strtbl; +#endif /* WBXML_ENCODER_USE_STRTBL */ +} + + +WBXML_DECLARE(void) wbxml_encoder_set_produce_anonymous(WBXMLEncoder *encoder, WB_BOOL set_anonymous) +{ + if (encoder == NULL) + return; + + encoder->produce_anonymous = set_anonymous; +} + + +WBXML_DECLARE(void) wbxml_encoder_set_wbxml_version(WBXMLEncoder *encoder, WBXMLVersion version) +{ + if (encoder == NULL) + return; + + if (version != WBXML_VERSION_UNKNOWN) + encoder->wbxml_version = version; +} + + +WBXML_DECLARE(void) wbxml_encoder_set_xml_gen_type(WBXMLEncoder *encoder, WBXMLGenXMLType gen_type) +{ + if (encoder == NULL) + return; + + encoder->xml_gen_type = gen_type; +} + + +WBXML_DECLARE(void) wbxml_encoder_set_indent(WBXMLEncoder *encoder, WB_UTINY indent) +{ + if (encoder == NULL) + return; + + encoder->indent_delta = indent; +} + + +WBXML_DECLARE(void) wbxml_encoder_set_tree(WBXMLEncoder *encoder, WBXMLTree *tree) +{ + if (encoder == NULL) + return; + + encoder->tree = tree; +} + + +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_tree_to_wbxml(WBXMLEncoder *encoder, WB_UTINY **wbxml, WB_ULONG *wbxml_len) +{ + WBXMLError ret = WBXML_OK; + + /* Check Parameters */ + if (encoder == NULL) + return WBXML_ERROR_BAD_PARAMETER; + + /* Init ret values */ + *wbxml = NULL; + *wbxml_len = 0; + + /* We output WBXML */ + wbxml_encoder_set_output_type(encoder, WBXML_ENCODER_OUTPUT_WBXML); + + /* Encode */ + if ((ret = encoder_encode_tree(encoder)) != WBXML_OK) + return ret; + + /* Get result */ + return wbxml_encoder_get_output(encoder, wbxml, wbxml_len); +} + + +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_tree_to_xml(WBXMLEncoder *encoder, WB_UTINY **xml, WB_ULONG *xml_len) +{ + WBXMLError ret = WBXML_OK; + + /* Check Parameters */ + if (encoder == NULL) + return WBXML_ERROR_BAD_PARAMETER; + + /* Init ret values */ + *xml = NULL; + *xml_len = 0; + + /* We output WBXML */ + wbxml_encoder_set_output_type(encoder, WBXML_ENCODER_OUTPUT_XML); + + /* Encode */ + if ((ret = encoder_encode_tree(encoder)) != WBXML_OK) + return ret; + + /* Get result */ + return wbxml_encoder_get_output(encoder, xml, xml_len); +} + + +WBXML_DECLARE(WBXMLError) wbxml_encoder_set_flow_mode(WBXMLEncoder *encoder, WB_BOOL flow_mode) +{ + if (encoder == NULL) + return WBXML_ERROR_BAD_PARAMETER; + + encoder->flow_mode = flow_mode; + + /* The string tables must only be disabled during flow mode. */ + if (flow_mode) + { + /* Don't use String Tables */ + wbxml_encoder_set_use_strtbl(encoder, FALSE); + } + + return WBXML_OK; +} + + +WBXML_DECLARE(void) wbxml_encoder_set_output_type(WBXMLEncoder *encoder, WBXMLEncoderOutputType output_type) +{ + if (encoder == NULL) + return; + + encoder->output_type = output_type; +} + + +WBXML_DECLARE(void) wbxml_encoder_set_lang(WBXMLEncoder *encoder, WBXMLLanguage lang) +{ + if (encoder == NULL) + return; + + encoder->lang = wbxml_tables_get_table(lang); +} + + +WBXML_DECLARE(void) wbxml_encoder_set_text_public_id(WBXMLEncoder *encoder, WB_BOOL gen_text) +{ + if (encoder == NULL) + return; + + encoder->textual_publicid = gen_text; +} + + +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_node(WBXMLEncoder *encoder, WBXMLTreeNode *node) +{ + if (encoder->flow_mode == FALSE) { + WBXML_WARNING((WBXML_ENCODER, "You should NOT call wbxml_encoder_encode_node() if you are not in Flow Mode encoding ! (use wbxml_encoder_set_flow_mode(encoder, TRUE))")); + } + + return wbxml_encoder_encode_node_with_elt_end(encoder, node, TRUE); +} + + +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_node_with_elt_end(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL enc_end) +{ + WB_ULONG prev_len = 0; + WBXMLError ret = WBXML_OK; + + if ((encoder == NULL) || (node == NULL)) + return WBXML_ERROR_BAD_PARAMETER; + + /* Check that language table has been set */ + if (encoder->lang == NULL) + return WBXML_ERROR_BAD_PARAMETER; + + /* Init Output Buffer if needed */ + if (!encoder_init_output(encoder)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Backup length */ + prev_len = wbxml_buffer_len(encoder->output); + + /* Check if result header is not already built */ + if ((encoder->flow_mode == TRUE) && (encoder->output_header == NULL) && + !((encoder->xml_encode_header == FALSE) && (encoder->output_type == WBXML_ENCODER_OUTPUT_XML))) + { + /* Build result header */ + switch (encoder->output_type) { + case WBXML_ENCODER_OUTPUT_XML: + if ((encoder->output_header = wbxml_buffer_create("", 0, WBXML_ENCODER_XML_HEADER_MALLOC_BLOCK)) == NULL) + ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; + else + ret = xml_fill_header(encoder, encoder->output_header); + break; + + case WBXML_ENCODER_OUTPUT_WBXML: + if ((encoder->output_header = wbxml_buffer_create("", 0, WBXML_ENCODER_WBXML_HEADER_MALLOC_BLOCK)) == NULL) + ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; + else + ret = wbxml_fill_header(encoder, encoder->output_header); + break; + + default: + ret = WBXML_ERROR_BAD_PARAMETER; + break; + } + } + + if (ret != WBXML_OK) + return ret; + + if ((ret = parse_node(encoder, node, enc_end)) == WBXML_OK) + encoder->pre_last_node_len = prev_len; + + return ret; +} + + +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_tree(WBXMLEncoder *encoder, WBXMLTree *tree) +{ + const WBXMLLangEntry *lang = NULL; + WBXMLError ret = WBXML_OK; + + if ((encoder == NULL) || (tree == NULL)) + return WBXML_ERROR_BAD_PARAMETER; + + /* Backup encoder lang */ + lang = encoder->lang; + + /* Set Tree lang to encoder */ + encoder->lang = tree->lang; + + /* Encode root node */ + ret = wbxml_encoder_encode_node(encoder, tree->root); + + /* Revert encoder lang */ + encoder->lang = lang; + + return ret; +} + + +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_raw_elt_start(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content) +{ + /* Init Output Buffer if needed */ + if (!encoder_init_output(encoder)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + return parse_element(encoder, node, has_content); +} + + +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_raw_elt_end(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content) +{ + /* Init Output Buffer if needed */ + if (!encoder_init_output(encoder)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + return parse_element_end(encoder, node, has_content); +} + + +WBXML_DECLARE(WBXMLError) wbxml_encoder_get_output(WBXMLEncoder *encoder, WB_UTINY **result, WB_ULONG *result_len) +{ + if ((encoder == NULL) || (result == NULL) || (result_len == NULL)) + return WBXML_ERROR_BAD_PARAMETER; + + switch (encoder->output_type) { + case WBXML_ENCODER_OUTPUT_XML: + return xml_build_result(encoder, result, result_len); + + case WBXML_ENCODER_OUTPUT_WBXML: + return wbxml_build_result(encoder, result, result_len); + + default: + return WBXML_ERROR_BAD_PARAMETER; + } +} + + +WBXML_DECLARE(WB_ULONG) wbxml_encoder_get_output_len(WBXMLEncoder *encoder) +{ + if (encoder == NULL) + return 0; + + return wbxml_buffer_len(encoder->output_header) + wbxml_buffer_len(encoder->output); +} + + +WBXML_DECLARE(void) wbxml_encoder_delete_output_bytes(WBXMLEncoder *encoder, WB_ULONG nb) +{ + if (encoder == NULL) + return; + + wbxml_buffer_delete(encoder->output, wbxml_buffer_len(encoder->output) - nb, nb); +} + + +WBXML_DECLARE(void) wbxml_encoder_delete_last_node(WBXMLEncoder *encoder) +{ + if (encoder == NULL) + return; + + wbxml_encoder_delete_output_bytes(encoder, wbxml_buffer_len(encoder->output) - encoder->pre_last_node_len); +} + + +/*************************************************** + * Private Functions + */ + +/**************************** + * Common Functions + */ + +#if 0 +/** + * @brief Convert a char to UCS-4 + * @param ch [in] The character to convert + * @param result [out] The UCS-4 code + * @return TRUE if convertion succeeded, FALSE otherwise + */ +static WB_BOOL convert_char_to_ucs4(WB_UTINY ch, WB_ULONG *result) +{ + /** @todo convert_char_to_ucs4() */ + + return FALSE; +} +#endif /* 0 */ + +/** + * @brief Duplicate a WBXML Encoder + * @param encoder [in] The WBXML Encoder to Duplicate + * @return The duplicated WBXML Encoder, or NULL if error + * @note Only options (parameters) fields are duplicated, others are reset + */ +static WBXMLEncoder *encoder_duplicate(WBXMLEncoder *encoder) +{ + WBXMLEncoder *result = NULL; + + if ((result = wbxml_encoder_create()) == NULL) + return NULL; + + result->ignore_empty_text = encoder->ignore_empty_text; + result->remove_text_blanks = encoder->remove_text_blanks; + + result->output_type = encoder->output_type; + result->xml_gen_type = encoder->xml_gen_type; + + result->indent_delta = encoder->indent_delta; + result->indent = encoder->indent; + +#if defined( WBXML_ENCODER_USE_STRTBL ) + result->use_strtbl = encoder->use_strtbl; +#endif /* WBXML_ENCODER_USE_STRTBL */ + + /* Do NOT generate XML Header */ + result->xml_encode_header = FALSE; + + result->wbxml_version = encoder->wbxml_version; + + return result; +} + + +static WBXMLError encoder_encode_tree(WBXMLEncoder *encoder) +{ + WBXMLError ret = WBXML_OK; + + /* Check Parameters */ + if ((encoder == NULL) || (encoder->tree == NULL) || ((encoder->lang == NULL) && (encoder->tree->lang == NULL)) || + ((encoder->output_type != WBXML_ENCODER_OUTPUT_XML) && (encoder->output_type != WBXML_ENCODER_OUTPUT_WBXML))) + { + return WBXML_ERROR_BAD_PARAMETER; + } + + if (encoder->lang == NULL) + encoder->lang = encoder->tree->lang; + + /* Choose Output Charset */ + if (encoder->output_charset == WBXML_CHARSET_UNKNOWN) { + /* User has not choosen the Output Charset Encoding */ + if (encoder->tree->orig_charset != WBXML_CHARSET_UNKNOWN) { + /* Use the original Charset Encoding found when we have parsed the original document */ + encoder->output_charset = encoder->tree->orig_charset; + } + else { + /* Use default charset */ + encoder->output_charset = WBXML_ENCODER_XML_DEFAULT_CHARSET; + } + } + + /* Init Output Buffer */ + if (!encoder_init_output(encoder)) { + wbxml_encoder_destroy(encoder); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + +#if defined( WBXML_ENCODER_USE_STRTBL ) + + if (encoder->output_type == WBXML_ENCODER_OUTPUT_WBXML) { + /* Choose if we will use String Table */ + switch (encoder->lang->langID) + { + #if defined( WBXML_SUPPORT_WV ) + /* Wireless-Village CSP 1.1 / 1.2: content can be tokenized, so we mustn't interfere with String Table stuff */ + case WBXML_LANG_WV_CSP11: + case WBXML_LANG_WV_CSP12: + encoder->use_strtbl = FALSE; + break; + #endif /* WBXML_SUPPORT_WV */ + + #if defined( WBXML_SUPPORT_OTA_SETTINGS ) + /* Nokia Ericsson OTA Settings : string tables are not supported */ + case WBXML_LANG_OTA_SETTINGS: + encoder->use_strtbl = FALSE; + break; + #endif /* WBXML_SUPPORT_OTA_SETTINGS */ + + default: + /* Use Default Value */ + break; + } + + /* Init String Table */ + if (encoder->use_strtbl) { + /** + * @bug If 'output_charset' is different from UTF-8, the string table initialization + * also is erroneous !!! + */ + if ((ret = wbxml_strtbl_initialize(encoder, encoder->tree->root)) != WBXML_OK) + return ret; + } + } + +#endif /* WBXML_ENCODER_USE_STRTBL */ + + /* Let's begin WBXML Tree Parsing */ + return parse_node(encoder, encoder->tree->root, TRUE); +} + + +static WB_BOOL encoder_init_output(WBXMLEncoder *encoder) +{ + WB_ULONG malloc_block = 0; + + if (encoder == NULL) + return FALSE; + + /* Check if output already inited */ + if (encoder->output != NULL) + return TRUE; + + /* Get malloc block */ + if (encoder->output_type == WBXML_ENCODER_OUTPUT_WBXML) + malloc_block = WBXML_ENCODER_WBXML_DOC_MALLOC_BLOCK; + else + malloc_block = WBXML_ENCODER_XML_DOC_MALLOC_BLOCK; + + /* Init Output Buffer */ + encoder->output = wbxml_buffer_create("", 0, malloc_block); + if (encoder->output == NULL) + return FALSE; + + return TRUE; +} + + +/********************************* + * WBXML Tree Parsing Functions + */ + +/** + * @brief Parse an XML Node + * @param encoder The WBXML Encoder + * @param node The node to parse + * @param enc_end If node is an element, do we encoded its end ? + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note We have recurrency in this function + */ +static WBXMLError parse_node(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL enc_end) +{ + WBXMLError ret = WBXML_OK; + + /* Set current node */ + encoder->current_node = node; + + /* Parse this node */ + switch (node->type) { + case WBXML_TREE_ELEMENT_NODE: + ret = parse_element(encoder, node, node->children != NULL); + break; + case WBXML_TREE_TEXT_NODE: + ret = parse_text(encoder, node); + break; + case WBXML_TREE_CDATA_NODE: + ret = parse_cdata(encoder); + break; + case WBXML_TREE_PI_NODE: + ret = parse_pi(encoder, node); + break; + case WBXML_TREE_TREE_NODE: + ret = parse_tree(encoder, node); + break; + default: + return WBXML_ERROR_XML_NODE_NOT_ALLOWED; + } + + if (ret != WBXML_OK) + return ret; + + /* Check if node has children */ + if (node->children != NULL) { + /* Parse Child */ + if ((ret = parse_node(encoder, node->children, TRUE)) != WBXML_OK) + return ret; + } + + /* Handle end of Element or CDATA section */ + switch (node->type) { + case WBXML_TREE_ELEMENT_NODE: + if (enc_end) { + switch(encoder->output_type) { + case WBXML_ENCODER_OUTPUT_XML: +#if defined( WBXML_ENCODER_XML_GEN_EMPTY_ELT ) + if (node->children != NULL) { +#endif /* WBXML_ENCODER_XML_GEN_EMPTY_ELT */ + + /* Encode end tag */ + if ((ret = xml_encode_end_tag(encoder, node)) != WBXML_OK) + return ret; + + WBXML_DEBUG((WBXML_ENCODER, "End Element")); + +#if defined( WBXML_ENCODER_XML_GEN_EMPTY_ELT ) + } +#endif /* WBXML_ENCODER_XML_GEN_EMPTY_ELT */ + break; + + case WBXML_ENCODER_OUTPUT_WBXML: + if (node->children != NULL) { + /* Add a WBXML End tag */ + if ((ret = wbxml_encode_end(encoder)) != WBXML_OK) + return ret; + + WBXML_DEBUG((WBXML_ENCODER, "End Element")); + } + break; + + default: + /* hu ? */ + break; + } /* switch */ + } /* if */ + break; + + case WBXML_TREE_CDATA_NODE: + /* End of CDATA section */ + encoder->in_cdata = FALSE; + + WBXML_DEBUG((WBXML_ENCODER, "End CDATA")); + + switch(encoder->output_type) { + case WBXML_ENCODER_OUTPUT_XML: + /* Encode XML "End of CDATA section" */ + if ((ret = xml_encode_end_cdata(encoder)) != WBXML_OK) + return ret; + break; + + case WBXML_ENCODER_OUTPUT_WBXML: + if (encoder->cdata == NULL) { + /* Must never happen */ + return WBXML_ERROR_INTERNAL; + } + + /* Encode CDATA Buffer into Opaque */ + /* NOTE: A CDATA section is not necessarily opaque data. + * NOTE: CDATA is only character data which can be NULL terminated. + * NOTE: Nevertheless it is not wrong to handle it like opaque data. + */ + if (wbxml_buffer_len(encoder->cdata) > 0) { + if ((ret = wbxml_encode_opaque(encoder, encoder->cdata)) != WBXML_OK) + return ret; + } + + /* Reset CDATA Buffer */ + wbxml_buffer_destroy(encoder->cdata); + encoder->cdata = NULL; + break; + + default: + /* hu ? */ + break; + } /* switch */ + break; + + default: + /* NOP */ + break; + } + + /* Reset Current Tag and Current Node */ + encoder->current_tag = NULL; + encoder->current_node = NULL; + + /* Parse next node */ + if (node->next != NULL) + return parse_node(encoder, node->next, TRUE); + else + return WBXML_OK; +} + + +/** + * @brief Parse an XML Element + * @param encoder The WBXML Encoder + * @param node The element to parse + * @param has_content Does the element has content ? + * @return WBXML_OK if parsing is OK, an error code otherwise + */ +static WBXMLError parse_element(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content) +{ + WB_ULONG i = 0; + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_ENCODER, "Element: <%s>", wbxml_tag_get_xml_name(node->name))); + + /* Encode: Element Name */ + switch (encoder->output_type) { + case WBXML_ENCODER_OUTPUT_WBXML: + if ((ret = wbxml_encode_tag(encoder, node, has_content)) != WBXML_OK) + return ret; + break; + + case WBXML_ENCODER_OUTPUT_XML: + if ((ret = xml_encode_tag(encoder, node)) != WBXML_OK) + return ret; + break; + + default: + return WBXML_ERROR_INTERNAL; + } + + /** @todo Check handling of Namespaces */ + + /** @todo For Canonical XML Output: Attributes MUST be sorted */ + + /* Parse: Attributes List */ + if (node->attrs != NULL) + { + for (i = 0; i < wbxml_list_len(node->attrs); i++) { + /* Parse: Attribute */ + if ((ret = parse_attribute(encoder, wbxml_list_get(node->attrs, i))) != WBXML_OK) + return ret; + } + } + + /* Encode: End of attributes */ + switch (encoder->output_type) { + case WBXML_ENCODER_OUTPUT_WBXML: + /** @todo Check if the attributes will really be tokenized. There can be ignored attributes, and so NO attribute + * tokenized at all. + */ + if ((node->attrs != NULL) && (encoder->lang->attrTable != NULL) /** @todo Fast patch for SyncML (change this) */) { + if ((ret = wbxml_encode_end(encoder)) != WBXML_OK) + return ret; + + WBXML_DEBUG((WBXML_ENCODER, "End Attributes")); + } + break; + + case WBXML_ENCODER_OUTPUT_XML: + /* Encode end of attributes */ + if ((ret = xml_encode_end_attrs(encoder, node)) != WBXML_OK) + return ret; + + WBXML_DEBUG((WBXML_ENCODER, "End Attributes")); + break; + + default: + return WBXML_ERROR_INTERNAL; + } + + return WBXML_OK; +} + + +/** + * @brief Parse an Element End + * @param encoder The WBXML Encoder + * @param node The element to parse + * @param has_content Does the element has content ? + * @return WBXML_OK if parsing is OK, an error code otherwise + */ +static WBXMLError parse_element_end(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content) +{ + WBXMLError ret = WBXML_OK; + + if (encoder->output_type == WBXML_ENCODER_OUTPUT_XML) { +#if defined( WBXML_ENCODER_XML_GEN_EMPTY_ELT ) + if (has_content) { +#endif /* WBXML_ENCODER_XML_GEN_EMPTY_ELT */ + + /* Encode end tag */ + ret = xml_encode_end_tag(encoder, node); + + WBXML_DEBUG((WBXML_ENCODER, "End Element")); + +#if defined( WBXML_ENCODER_XML_GEN_EMPTY_ELT ) + } +#endif /* WBXML_ENCODER_XML_GEN_EMPTY_ELT */ + } + else if (encoder->output_type == WBXML_ENCODER_OUTPUT_WBXML) { + if (has_content) { + /* Add a WBXML End tag */ + ret = wbxml_encode_end(encoder); + + WBXML_DEBUG((WBXML_ENCODER, "End Element")); + } + } + + return ret; +} + + +/** + * @brief Parse an XML Attribute + * @param encoder The WBXML Encoder + * @param attribute The XML Attribute to parse + * @return WBXML_OK if parsing is OK, an error code otherwise + */ +static WBXMLError parse_attribute(WBXMLEncoder *encoder, WBXMLAttribute *attribute) +{ + if (encoder->lang == NULL) + return WBXML_ERROR_LANG_TABLE_UNDEFINED; + + if (encoder->lang->attrTable == NULL) + return WBXML_OK; + + /* Check that this attribute has a name */ + if (attribute->name == NULL) + return WBXML_ERROR_XML_NULL_ATTR_NAME; + + WBXML_DEBUG((WBXML_ENCODER, "Attribute: %s = %s", wbxml_attribute_get_xml_name(attribute), wbxml_attribute_get_xml_value(attribute))); + + /* Encode: Attribute */ + switch (encoder->output_type) { + case WBXML_ENCODER_OUTPUT_WBXML: + return wbxml_encode_attr(encoder, attribute); + + case WBXML_ENCODER_OUTPUT_XML: + return xml_encode_attr(encoder, attribute); + + default: + return WBXML_ERROR_INTERNAL; + } +} + + +/** + * @brief Parse an XML Text + * @param encoder The WBXML Encoder + * @param node The text to parse + * @return WBXML_OK if parsing is OK, an error code otherwise + */ +static WBXMLError parse_text(WBXMLEncoder *encoder, WBXMLTreeNode *node) +{ + WBXMLError ret = WBXML_OK; + + /* Some elements should be transferred as opaque data */ + if (encoder->output_type == WBXML_ENCODER_OUTPUT_WBXML && + encoder->current_tag != NULL && + encoder->current_tag->options & WBXML_TAG_OPTION_BINARY) + { + return wbxml_encode_opaque(encoder, node->content); + } + + /* Do not modify text inside a CDATA section */ + /* Do not modify text inside a BINARY section */ + if (!encoder->in_cdata && + ! (encoder->current_tag != NULL && encoder->current_tag->options & WBXML_TAG_OPTION_BINARY)) { + /* If Canonical Form: "Ignorable white space is considered significant and is treated equivalently to data" */ + if ((encoder->output_type != WBXML_ENCODER_OUTPUT_XML) || (encoder->xml_gen_type != WBXML_GEN_XML_CANONICAL)) { + /* Ignore blank nodes */ + if ((encoder->ignore_empty_text) && (wbxml_buffer_contains_only_whitespaces(node->content))) + return WBXML_OK; + + /* Strip Blanks */ + if (encoder->remove_text_blanks) + wbxml_buffer_strip_blanks(node->content); + } + } + + WBXML_DEBUG((WBXML_ENCODER, "Text: <%s>", wbxml_buffer_get_cstr(node->content))); + + /* Encode Text */ + switch (encoder->output_type) { + case WBXML_ENCODER_OUTPUT_WBXML: + if (encoder->in_cdata) { + if (encoder->cdata == NULL) { + /* Must never happen */ + return WBXML_ERROR_INTERNAL; + } + +#if defined( WBXML_SUPPORT_SYNCML ) + + if ((encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML10) || + (encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML11) || + (encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML12)) + { + /** @todo We suppose that Opaque Data in SyncML messages can only be vCard or vCal documents. CHANGE THAT ! */ + if (node->content != NULL) { + if (wbxml_buffer_get_cstr(node->content)[0] == 0x0a && wbxml_buffer_len(node->content) == 1) { + wbxml_buffer_insert_cstr(node->content, (WB_UTINY*) "\r", 0); + } + } + } + +#endif /* WBXML_SUPPORT_SYNCML */ + + /* Add text into CDATA Buffer */ + if (!wbxml_buffer_append(encoder->cdata, node->content)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; + } + else { + /* Encode text */ + encoder->current_text_parent = node->parent; + ret = wbxml_encode_value_element_buffer(encoder, wbxml_buffer_get_cstr(node->content), WBXML_VALUE_ELEMENT_CTX_CONTENT); + encoder->current_text_parent = NULL; + return ret; + } + + case WBXML_ENCODER_OUTPUT_XML: + return xml_encode_text(encoder, node); + + default: + return WBXML_ERROR_INTERNAL; + } +} + + +/** + * @brief Parse an XML CDATA + * @param encoder The WBXML Encoder + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note There is no node parameter because the content is not + * handled by this function and CDATA has no "attributes". + */ +static WBXMLError parse_cdata(WBXMLEncoder *encoder) +{ + WBXML_DEBUG((WBXML_ENCODER, "CDATA Begin")); + + /* Keep in mind that we are in a CDATA section */ + encoder->in_cdata = TRUE; + + /* Encode CDATA */ + switch (encoder->output_type) { + case WBXML_ENCODER_OUTPUT_WBXML: + if (encoder->cdata != NULL) { + /* Must never happend */ + return WBXML_ERROR_INTERNAL; + } + + /* Create a new CDATA Buffer */ + if ((encoder->cdata = wbxml_buffer_create("", 0, 0)) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + return WBXML_OK; + case WBXML_ENCODER_OUTPUT_XML: + return xml_encode_cdata(encoder); + default: + return WBXML_ERROR_INTERNAL; + } +} + + +/** + * @brief Parse an XML PI + * @param encoder The WBXML Encoder + * @param node The PI to parse + * @return WBXML_OK if parsing is OK, an error code otherwise + */ +static WBXMLError parse_pi(WBXMLEncoder *encoder, WBXMLTreeNode *node) +{ + /** @todo parse_pi() */ + + return WBXML_ERROR_NOT_IMPLEMENTED; +} + + +/** + * @brief Parse a WBXML Tree + * @param encoder The WBXML Encoder + * @param node The WBXML Tree to parse + * @return WBXML_OK if parsing is OK, an error code otherwise + */ +static WBXMLError parse_tree(WBXMLEncoder *encoder, WBXMLTreeNode *node) +{ + switch (encoder->output_type) { + case WBXML_ENCODER_OUTPUT_WBXML: + return wbxml_encode_tree(encoder, node->tree); + case WBXML_ENCODER_OUTPUT_XML: + return xml_encode_tree(encoder, node->tree); + default: + return WBXML_ERROR_INTERNAL; + } +} + + +/***************************************** + * WBXML Output Functions + */ + +/**************************** + * Build WBXML Result + */ + +/** + * @brief Build WBXML Result + * @param encoder [in] The WBXML Encoder + * @param wbxml [out] Resulting WBXML document + * @param wbxml_len [out] The resulting WBXML document length + * @return WBXML_OK if built is OK, an error code otherwise + * @note WBXML Header = version publicid charset length + */ +static WBXMLError wbxml_build_result(WBXMLEncoder *encoder, WB_UTINY **wbxml, WB_ULONG *wbxml_len) +{ + WBXMLBuffer *header = NULL; + WBXMLError ret = WBXML_OK; + + if (encoder->flow_mode == TRUE) { + /* Header already built */ + header = encoder->output_header; + } + else { + /* Create WBXML Header buffer */ + if ((header = wbxml_buffer_create("", 0, WBXML_ENCODER_WBXML_HEADER_MALLOC_BLOCK)) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Fill Header Buffer */ + if ((ret = wbxml_fill_header(encoder, header)) != WBXML_OK) { + wbxml_buffer_destroy(header); + return ret; + } + } + + /* Result Buffer Length */ + *wbxml_len = wbxml_buffer_len(header) + wbxml_buffer_len(encoder->output); + + /* Create Result Buffer */ + *wbxml = (WB_UTINY *) wbxml_malloc(*wbxml_len * sizeof(WB_UTINY)); + if (*wbxml == NULL) { + if (encoder->flow_mode == FALSE) + wbxml_buffer_destroy(header); + + *wbxml_len = 0; + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Copy WBXML Header */ + memcpy(*wbxml, wbxml_buffer_get_cstr(header), wbxml_buffer_len(header)); + + /* Copy WBXML Buffer */ + memcpy(*wbxml + wbxml_buffer_len(header), wbxml_buffer_get_cstr(encoder->output), wbxml_buffer_len(encoder->output)); + + if (encoder->flow_mode == FALSE) + wbxml_buffer_destroy(header); + + return WBXML_OK; +} + + +static WBXMLError wbxml_fill_header(WBXMLEncoder *encoder, WBXMLBuffer *header) +{ + WBXMLBuffer *pid = NULL; + WB_ULONG public_id = 0, public_id_index = 0, strstbl_len = 0; + WB_BOOL pi_in_strtbl = FALSE; + WBXMLError ret = WBXML_OK; + +#if defined( WBXML_ENCODER_USE_STRTBL ) + WBXMLStringTableElement *elt = NULL; + WB_BOOL added = FALSE; + + strstbl_len = encoder->strstbl_len; +#endif /* WBXML_ENCODER_USE_STRTBL */ + + if ((encoder == NULL) || (encoder->lang == NULL) || (encoder->lang->publicID == NULL) || (header == NULL)) + return WBXML_ERROR_BAD_PARAMETER; + + /* WBXML Public ID */ + public_id = encoder->lang->publicID->wbxmlPublicID; + + /* Encode WBXML Version */ + if (!wbxml_buffer_append_char(header, (WB_UTINY) encoder->wbxml_version)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Encode Public ID */ + /* If WBXML Public Id is '0x01' (unknown), or we forced it, add the XML Public ID in the String Table */ + if ((encoder->textual_publicid || (public_id == WBXML_PUBLIC_ID_UNKNOWN)) && + !encoder->produce_anonymous) + { + if (encoder->lang->publicID->xmlPublicID != NULL) + { + if ((pid = wbxml_buffer_create(encoder->lang->publicID->xmlPublicID, + WBXML_STRLEN(encoder->lang->publicID->xmlPublicID), + WBXML_STRLEN(encoder->lang->publicID->xmlPublicID))) == NULL) + { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + +#if defined( WBXML_ENCODER_USE_STRTBL ) + if (encoder->use_strtbl) { + if ((elt = wbxml_strtbl_element_create(pid, FALSE)) == NULL) + { + wbxml_buffer_destroy(pid); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + if (!wbxml_strtbl_add_element(encoder, + elt, + &public_id_index, + &added)) + { + wbxml_strtbl_element_destroy(elt); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + if (!added) + wbxml_strtbl_element_destroy(elt); + + strstbl_len = encoder->strstbl_len; + } + else { +#endif /* WBXML_ENCODER_USE_STRTBL */ + /* Length of String Table is length of XML Public ID (plus the NULL char) */ + strstbl_len = wbxml_buffer_len(pid) + 1; + + /* There is only the XML Public ID in String Table */ + public_id_index = 0; +#if defined( WBXML_ENCODER_USE_STRTBL ) + } +#endif /* WBXML_ENCODER_USE_STRTBL */ + + pi_in_strtbl = TRUE; + } + } + + /* publicid = mb_u_int32 | ( zero index ) */ + if (pi_in_strtbl) { + /* Encode XML Public ID String Table index */ + if (!wbxml_buffer_append_char(header, 0x00) || + !wbxml_buffer_append_mb_uint_32(header, public_id_index)) + { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + else { + /* Encode WBXML Public ID */ + if (!wbxml_buffer_append_mb_uint_32(header, public_id)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + /* Encode Charset (default: UTF-8) and String Table Length */ + /** @todo Handle correctly the charset */ + if (!wbxml_buffer_append_mb_uint_32(header, WBXML_ENCODER_DEFAULT_CHARSET) || + !wbxml_buffer_append_mb_uint_32(header, strstbl_len)) + { + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + /* Copy WBXML String Table */ +#if defined( WBXML_ENCODER_USE_STRTBL ) + if (encoder->use_strtbl) { + if ((ret = wbxml_strtbl_construct(header,(WBXMLList *) encoder->strstbl)) != WBXML_OK) + return ret; + } + else { +#endif /* WBXML_ENCODER_USE_STRTBL */ + + if (pid != NULL) { + if (!wbxml_buffer_append(header, pid)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + if (!wbxml_buffer_append_char(header, WBXML_STR_END)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Clean up */ + wbxml_buffer_destroy(pid); + } + +#if defined( WBXML_ENCODER_USE_STRTBL ) + } +#endif /* WBXML_ENCODER_USE_STRTBL */ + + return WBXML_OK; +} + + +/**************************** + * WBXML Encoding Functions + */ + +/** + * @brief Encode a WBXML End Token + * @param encoder The WBXML Encoder + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError wbxml_encode_end(WBXMLEncoder *encoder) +{ + /* Append END */ + if (!wbxml_buffer_append_char(encoder->output, WBXML_END)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} + + +/** + * @brief Encode a WBXML Tag + * @param encoder The WBXML Encoder + * @param node The element to encode + * @param has_content Does the element has content ? + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError wbxml_encode_tag(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content) +{ + const WBXMLTagEntry *tag = NULL; + WB_UTINY token = 0x00, page = 0x00; + + if (node->name->type == WBXML_VALUE_TOKEN) { + token = node->name->u.token->wbxmlToken; + page = node->name->u.token->wbxmlCodePage; + + /* Current Tag */ + encoder->current_tag = node->name->u.token; + } + else { + /* Search tag in Tags Table */ + if ((tag = wbxml_tables_get_tag_from_xml(encoder->lang, encoder->tagCodePage, wbxml_tag_get_xml_name(node->name))) != NULL) + { + token = tag->wbxmlToken; + page = tag->wbxmlCodePage; + + /* Current Tag */ + encoder->current_tag = tag; + } + else + encoder->current_tag = NULL; + } + + /* Check if this element has content */ + if (has_content) + token |= WBXML_TOKEN_WITH_CONTENT; + + /* Check if this element has attributes */ + /** @todo Check if the attributes will really be tokenized. There can be ignored attributes, and so NO attribute + * tokenized at all. + */ + if ((node->attrs != NULL) && (encoder->lang->attrTable != NULL) /** @todo Fast patch for SyncML (change this) */) + token |= WBXML_TOKEN_WITH_ATTRS; + + /* Encode Token */ + if ((token & WBXML_TOKEN_MASK) == 0x00) + return wbxml_encode_tag_literal(encoder, (WB_UTINY *) wbxml_tag_get_xml_name(node->name), token); + else + return wbxml_encode_tag_token(encoder, token, page); +} + + +/** + * @brief Encode a WBXML Literal Token + * @param encoder The WBXML Encoder + * @param tag The literal tag to encode + * @param mask The WBXML Mask for this tag + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note stag = (literalTag index) + * literalTag = LITERAL | LITERAL_A | LITERAL_C | LITERAL_AC + * index = mb_u_int32 + */ +static WBXMLError wbxml_encode_tag_literal(WBXMLEncoder *encoder, const WB_UTINY *tag, WB_UTINY mask) +{ +#if defined( WBXML_ENCODER_USE_STRTBL ) + WBXMLStringTableElement *elt = NULL; + WBXMLBuffer *buff = NULL; + WB_ULONG index = 0; + WB_BOOL added = FALSE; + + /* If String Table generation is disabled, we can't generate this Literal Tag */ + if (!encoder->use_strtbl) + return WBXML_ERROR_STRTBL_DISABLED; + + /* Add tag in String Table */ + if (((buff = wbxml_buffer_create(tag, WBXML_STRLEN(tag), WBXML_STRLEN(tag))) == NULL) || + ((elt = wbxml_strtbl_element_create(buff, FALSE)) == NULL) || + (!wbxml_strtbl_add_element(encoder, elt, &index, &added))) + { + wbxml_strtbl_element_destroy(elt); + wbxml_buffer_destroy(buff); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* If already exists in String Table: clean-up */ + if (!added) + wbxml_strtbl_element_destroy(elt); + + /* Encode literalTag index */ + if ((!wbxml_buffer_append_char(encoder->output, (WB_UTINY) (WBXML_LITERAL | mask))) || + (!wbxml_buffer_append_mb_uint_32(encoder->output, index))) + { + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + return WBXML_OK; +#else + /* No String Table Support */ + return WBXML_ERROR_STRTBL_DISABLED; +#endif /* WBXML_ENCODER_USE_STRTBL */ +} + + +/** + * @brief Encode a WBXML Tag Token + * @param encoder The WBXML Encoder + * @param token The WBXML Tag Token to encode + * @param page The WBXML CodePage for this Token + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note element = ([switchPage] stag) + * switchPage = SWITCH_PAGE pageindex + * stag = TAG + * pageindex = u_int8 + */ +static WBXMLError wbxml_encode_tag_token(WBXMLEncoder *encoder, WB_UTINY token, WB_UTINY page) +{ + /* Switch Page if needed */ + if (encoder->tagCodePage != page) + { + if ((!wbxml_buffer_append_char(encoder->output, WBXML_SWITCH_PAGE)) || + (!wbxml_buffer_append_char(encoder->output, page))) + { + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + encoder->tagCodePage = page; + } + + /* Add Token */ + if (!wbxml_buffer_append_char(encoder->output, token)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} + + +/** + * @brief Encode a WBXML Attribute + * @param encoder [in] The WBXML Encoder + * @param attribute [in] The Attribute to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note attribute = attrStart *attrValue + */ +static WBXMLError wbxml_encode_attr(WBXMLEncoder *encoder, WBXMLAttribute *attribute) +{ + WB_UTINY *value = NULL; + WBXMLError ret = WBXML_OK; + + /* Encode Attribute Start */ + if ((ret = wbxml_encode_attr_start(encoder, attribute, &value)) != WBXML_OK) + return ret; + + /* Encode Attribute Value */ + if (value != NULL) { + if ((ret = wbxml_encode_value_element_buffer(encoder, value, WBXML_VALUE_ELEMENT_CTX_ATTR)) != WBXML_OK) + return ret; + } + + /* Reset Current Attribute */ + encoder->current_attr = NULL; + + return WBXML_OK; +} + + +/** + * @brief Encode a WBXML Attribute Start + * @param encoder [in] The WBXML Encoder + * @param attribute [in] The Attribute + * @param value [out] Pointer to the value to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note The 'value' result correspond to the value there is still to encode + * For example, in Wireless-Village, to encode: + * xmlns="http://www.wireless-village.org/CSP1.1" + * We first encode: + * xmlns="http://www.wireless-village.org/CSP (start token: 0x05) + * Then: + * "1.1" as an inline string + */ +static WBXMLError wbxml_encode_attr_start(WBXMLEncoder *encoder, WBXMLAttribute *attribute, WB_UTINY **value) +{ + const WBXMLAttrEntry *attr = NULL; + WB_UTINY *value_left = NULL; + WB_UTINY token = 0x00, page = 0x00; + + *value = wbxml_buffer_get_cstr(attribute->value); + + if (attribute->name->type == WBXML_VALUE_TOKEN) { + /* We already have Token / Page pair for this Attribute Start */ + token = attribute->name->u.token->wbxmlToken; + page = attribute->name->u.token->wbxmlCodePage; + + /* Current Attribute */ + encoder->current_attr = attribute->name->u.token; + + /* If there is a Start Value associated to the Attribute Name token... */ + if (attribute->name->u.token->xmlValue != NULL) + { + /* ... Check that we have it at start of full Attribute Value */ + if (WBXML_STRNCMP(wbxml_buffer_get_cstr(attribute->value), + attribute->name->u.token->xmlValue, + WBXML_STRLEN(attribute->name->u.token->xmlValue)) == 0) + { + /* Check if you have still a part in the Attribute Value to encode */ + if (wbxml_buffer_len(attribute->value) > WBXML_STRLEN(attribute->name->u.token->xmlValue)) + { + /* There is still a part in the Value to encode */ + *value = wbxml_buffer_get_cstr(attribute->value) + WBXML_STRLEN(attribute->name->u.token->xmlValue); + } + else + *value = NULL; + } + else { + /** @todo Should we stop everything and generate an error ? */ + WBXML_WARNING((WBXML_ENCODER, "wbxml_encode_attr_start() => Attribute Value doesn't match Attribute Token")); + + /* Current Attribute */ + encoder->current_attr = NULL; + + /* Encode Attribute Literal */ + return wbxml_encode_attr_start_literal(encoder, wbxml_attribute_get_xml_name(attribute)); + } + } + + /* Encode Attribute Token */ + return wbxml_encode_attr_token(encoder, token, page); + } + else { + /* Search in Attribute table */ + if ((attr = wbxml_tables_get_attr_from_xml(encoder->lang, + (WB_UTINY *)attribute->name->u.token->xmlName, + wbxml_buffer_get_cstr(attribute->value), + &value_left)) != NULL) + { + token = attr->wbxmlToken; + page = attr->wbxmlCodePage; + + /* Current Attribute */ + encoder->current_attr = attr; + + /* If there is still a part in Attribute Value to encode */ + *value = value_left; + + /* Encode Attribute Token */ + return wbxml_encode_attr_token(encoder, token, page); + } + else { + /* Current Attribute */ + encoder->current_attr = NULL; + + /* Encode Attribute Literal */ + return wbxml_encode_attr_start_literal(encoder, wbxml_attribute_get_xml_name(attribute)); + } + } +} + + +/** + * @brief Encode a WBXML Attribute Value + * @param encoder The WBXML Encoder + * @param buffer The Value Element Buffer to encode + * @param ctx Value Element Context (Attribute Value or Content) + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note attrStart = *attrValue + * attrValue = string | extension | entity | opaque + * + * AND: element = *content + * content = string | extension | entity | opaque + */ +static WBXMLError wbxml_encode_value_element_buffer(WBXMLEncoder *encoder, WB_UTINY *buffer, WBXMLValueElementCtx ctx) +{ + WBXMLList *lresult = NULL; + WBXMLBuffer *buff = NULL; + WBXMLValueElement *elt = NULL, *new_elt = NULL; + WB_ULONG i = 0, j = 0, index = 0; + WB_UTINY *the_buffer = buffer; + WBXMLError ret = WBXML_OK; + +#if defined( WBXML_ENCODER_USE_STRTBL ) + WBXMLStringTableElement *strtbl_elt = NULL; +#endif /* WBXML_ENCODER_USE_STRTBL */ + + if ((buffer == NULL) || (*buffer == '\0')) + return WBXML_OK; + + + /********************************************************* + * Encoder Language Specific Attribute Values + */ + + if (ctx == WBXML_VALUE_ELEMENT_CTX_ATTR) { + switch (encoder->lang->langID) { +#if defined( WBXML_SUPPORT_SI ) + case WBXML_LANG_SI10: + /* SI 1.0: Encode date for 'created' and 'si-expires' attributes */ + if (encoder->current_attr == NULL) + break; + + if ((encoder->current_attr->wbxmlCodePage == 0x00) && + ((encoder->current_attr->wbxmlToken == 0x0a) || (encoder->current_attr->wbxmlToken == 0x10))) + { + return wbxml_encode_datetime(encoder, buffer); + } + break; +#endif /* WBXML_SUPPORT_SI */ + +#if defined( WBXML_SUPPORT_EMN ) + case WBXML_LANG_EMN10: + /* EMN 1.0: Encode date for 'timestamp' attribute */ + if (encoder->current_attr == NULL) + break; + + if ((encoder->current_attr->wbxmlCodePage == 0x00) && (encoder->current_attr->wbxmlToken == 0x05)) + { + return wbxml_encode_datetime(encoder, buffer); + } + break; +#endif /* WBXML_SUPPORT_EMN */ + +#if defined( WBXML_SUPPORT_OTA_SETTINGS ) + case WBXML_LANG_OTA_SETTINGS: + /** + * Nokia OTA Settings support for the ICON value in bookmarks. + * The encoding is done using base64 encoded images in XML, and encoding it as OPAQUE data in the WBXML. + * The icon is embedded using an PARM element with name ICON. + */ + if ((encoder->current_attr->wbxmlCodePage == 0x00) && + (encoder->current_attr->wbxmlToken == 0x11)) + { + if ((ret = wbxml_encode_ota_nokia_icon(encoder, buffer)) != WBXML_NOT_ENCODED) + return ret; + } + break; +#endif /* WBXML_SUPPORT_OTA_SETTINGS */ + + default: + break; + } + } + + + /********************************************************* + * Encoder Language Specific Content Text Values + */ + + /* If this is a Text Content (not in a CDATA section) */ + if ((ctx == WBXML_VALUE_ELEMENT_CTX_CONTENT) && (!encoder->in_cdata)) + { +#if defined( WBXML_SUPPORT_WV ) + /* If this is a Wireless-Village 1.1 / 1.2 document */ + if ((encoder->lang->langID == WBXML_LANG_WV_CSP11) || + (encoder->lang->langID == WBXML_LANG_WV_CSP12)) + { + /* Here we try to encode Specific WV Content. If this buffer is not a WV Data Type buffer, or + * if it can't be FULLY encoded as an Extension Token, then this function returns WBXML_NOT_ENCODED. + * If so, the buffer will be encoded as String latter. + */ + if ((ret = wbxml_encode_wv_content(encoder, buffer)) != WBXML_NOT_ENCODED) + return ret; + } +#endif /* WBXML_SUPPORT_WV */ + +#if defined( WBXML_SUPPORT_DRMREL ) + /* If this is a DRMREL 1.0 document */ + if (encoder->lang->langID == WBXML_LANG_DRMREL10) + { + /* Here we try to encode Specific DRMREL Content. If this buffer is not a DRMREL Data Type buffer + * this function returns WBXML_NOT_ENCODED. + * If so, the buffer will be encoded as String latter. + */ + if ((ret = wbxml_encode_drmrel_content(encoder, buffer)) != WBXML_NOT_ENCODED) + return ret; + } +#endif /* WBXML_SUPPORT_DRMREL */ + +#if defined( WBXML_SUPPORT_SYNCML ) + /* If this is a SyncML document ? */ + if ((encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML10) || + (encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML11) || + (encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML12)) + { + /** @todo We must check too if we are in a */ + + /* Change text in from "application/vnd.syncml-devinf+xml" to "application/vnd.syncml-devinf+wbxml" */ + if (WBXML_STRCASECMP(buffer, "application/vnd.syncml-devinf+xml") == 0) { + the_buffer = (WB_UTINY*) "application/vnd.syncml-devinf+wbxml"; + } + /* Change text in from "application/vnd.syncml.dmtnds+xml" to "application/vnd.syncml.dmtnds+wbxml" */ + if (WBXML_STRCASECMP(buffer, "application/vnd.syncml.dmtnds+xml") == 0) { + the_buffer = (WB_UTINY*) "application/vnd.syncml.dmtnds+wbxml"; + } + } +#endif /* WBXML_SUPPORT_SYNCML */ + } + + + /********************************************************* + * @todo Search first for simple cases ! + */ + + + /********************************************************* + * We search the list of Value Elements that represents + * this Value buffer + */ + + /* Create Result List */ + if ((lresult = wbxml_list_create()) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Create primary Buffer */ + if ((buff = wbxml_buffer_create_from_cstr(the_buffer)) == NULL) { + wbxml_list_destroy(lresult, NULL); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Create Value Element for this buffer */ + if ((elt = wbxml_value_element_create()) == NULL) { + wbxml_buffer_destroy(buff); + wbxml_list_destroy(lresult, NULL); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + elt->type = WBXML_VALUE_ELEMENT_STRING; + elt->u.str = buff; + + /* Append this Buffer to Result List */ + if (!wbxml_list_append(lresult, elt)) { + wbxml_value_element_destroy(elt); + wbxml_list_destroy(lresult, NULL); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* If this is an Attribute Value */ + if (ctx == WBXML_VALUE_ELEMENT_CTX_ATTR) + { + /********************************************************* + * Search for Attribute Value Tokens + */ + + if (encoder->lang->attrValueTable != NULL) { + /* For each Attribute Value Token */ + j = 0; + while (encoder->lang->attrValueTable[j].xmlName != NULL) + { + /* For each Value Element */ + for (i = 0; i < wbxml_list_len(lresult); i++) { + if ((elt = (WBXMLValueElement *) wbxml_list_get(lresult, i)) == NULL) + continue; + + if (elt->type != WBXML_VALUE_ELEMENT_STRING) + continue; + + /* Is this Attribute Value contained in this Buffer ? */ + if (wbxml_buffer_search_cstr(elt->u.str, (WB_UTINY *)encoder->lang->attrValueTable[j].xmlName, 0, &index)) { + /* Create new Value Element */ + if ((new_elt = wbxml_value_element_create()) == NULL) { + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + new_elt->type = WBXML_VALUE_ELEMENT_ATTR_TOKEN; + new_elt->u.attr = &(encoder->lang->attrValueTable[j]); + + /* Insert new Value Element in List */ + if (!wbxml_list_insert(lresult, (void *) new_elt, i + 1)) { + wbxml_value_element_destroy(new_elt); + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Check if there is still the end of the String to encode */ + if (index + WBXML_STRLEN(encoder->lang->attrValueTable[j].xmlName) < wbxml_buffer_len(elt->u.str)) { + /* Create new Value Element */ + if ((new_elt = wbxml_value_element_create()) == NULL) { + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + new_elt->type = WBXML_VALUE_ELEMENT_STRING; + new_elt->u.str = wbxml_buffer_create_from_cstr(wbxml_buffer_get_cstr(elt->u.str) + index + WBXML_STRLEN(encoder->lang->attrValueTable[j].xmlName)); + + /* Insert new Value Element in List */ + if ((new_elt->u.str == NULL) || + !wbxml_list_insert(lresult, (void *) new_elt, i + 2)) + { + wbxml_value_element_destroy(new_elt); + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + + /* Remove the Attribute Value found in Value Element */ + wbxml_buffer_delete(elt->u.str, index, wbxml_buffer_len(elt->u.str) - index); + } /* if */ + } /* for */ + j++; + } /* while */ + } /* if */ + } + + /* If this is a Text Content (not in a CDATA section) */ + if ((ctx == WBXML_VALUE_ELEMENT_CTX_CONTENT) && (!encoder->in_cdata)) + { + /********************************************************* + * Search for Extension Tokens + */ + + /** @todo Finish Extension Tokens Search */ + + if (encoder->lang->extValueTable != NULL) { + /* For each Extension Token */ + j = 0; + while (encoder->lang->extValueTable[j].xmlName != NULL) + { + /* For each Value Element */ + for (i = 0; i < wbxml_list_len(lresult); i++) { + if ((elt = (WBXMLValueElement *) wbxml_list_get(lresult, i)) == NULL) + continue; + + if (elt->type != WBXML_VALUE_ELEMENT_STRING) + continue; + + /* Ignores the "1 char Extension Tokens" */ + if (WBXML_STRLEN(encoder->lang->extValueTable[j].xmlName) < 2) + continue; + + /* Is this Extension Token contained in this Buffer ? + * + * The Extension Token must start at the beginning of + * the buffer. Otherwise we can damage normal text + * entities like 'My IM-application.' If 'IM' is an + * Extension Token. + * + * Assumption: The buffer is already normalized. + */ + if (wbxml_buffer_compare_cstr(elt->u.str, (WB_TINY *) encoder->lang->extValueTable[j].xmlName) == 0) + { + /* Create new Value Element */ + if ((new_elt = wbxml_value_element_create()) == NULL) { + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + new_elt->type = WBXML_VALUE_ELEMENT_EXTENSION; + new_elt->u.ext = &(encoder->lang->extValueTable[j]); + + /* Insert new Value Element in List */ + if (!wbxml_list_insert(lresult, (void *) new_elt, i + 1)) { + wbxml_value_element_destroy(new_elt); + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Check if there is still the end of the String to encode */ + if (index + WBXML_STRLEN(encoder->lang->extValueTable[j].xmlName) < wbxml_buffer_len(elt->u.str)) { + /* Create new Value Element */ + if ((new_elt = wbxml_value_element_create()) == NULL) { + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + new_elt->type = WBXML_VALUE_ELEMENT_STRING; + new_elt->u.str = wbxml_buffer_create_from_cstr(wbxml_buffer_get_cstr(elt->u.str) + index + WBXML_STRLEN(encoder->lang->extValueTable[j].xmlName)); + + /* Insert new Value Element in List */ + if ((new_elt->u.str == NULL) || + !wbxml_list_insert(lresult, (void *) new_elt, i + 2)) + { + wbxml_value_element_destroy(new_elt); + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + + /* Remove the Attribute Value found in Value Element */ + wbxml_buffer_delete(elt->u.str, index, wbxml_buffer_len(elt->u.str) - index); + } /* if */ + } /* for */ + j++; + } /* while */ + } /* if */ + } + + +#if defined( WBXML_ENCODER_USE_STRTBL ) + + /*********************************************************************** + * Search for String Table References + * (except if this is a Content string and we are in a CDATA section) + */ + + if (encoder->use_strtbl && !(encoder->in_cdata && (ctx == WBXML_VALUE_ELEMENT_CTX_CONTENT))) { + /* For each String Table Element */ + for (j = 0; j < wbxml_list_len(encoder->strstbl); j++) { + if ((strtbl_elt = (WBXMLStringTableElement *) wbxml_list_get(encoder->strstbl, j)) == NULL) + continue; + + /* For each Value Element */ + for (i = 0; i < wbxml_list_len(lresult); i++) { + if ((elt = (WBXMLValueElement *) wbxml_list_get(lresult, i)) == NULL) + continue; + + if (elt->type != WBXML_VALUE_ELEMENT_STRING) + continue; + + /* Is the String Table Element contained in this Buffer ? */ + if (wbxml_buffer_search(elt->u.str, strtbl_elt->string, 0, &index)) { + /* Create new Value Element */ + if ((new_elt = wbxml_value_element_create()) == NULL) { + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + new_elt->type = WBXML_VALUE_ELEMENT_TABLEREF; + new_elt->u.index = strtbl_elt->offset; + + /* Insert new Value Element in List */ + if (!wbxml_list_insert(lresult, (void *) new_elt, i + 1)) { + wbxml_value_element_destroy(new_elt); + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Check if there is still the end of the String to encode */ + if (index + wbxml_buffer_len(strtbl_elt->string) < wbxml_buffer_len(elt->u.str)) { + /* Create new Value Element */ + if ((new_elt = wbxml_value_element_create()) == NULL) { + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + new_elt->type = WBXML_VALUE_ELEMENT_STRING; + new_elt->u.str = wbxml_buffer_create_from_cstr(wbxml_buffer_get_cstr(elt->u.str) + index + wbxml_buffer_len(strtbl_elt->string)); + + /* Insert new Value Element in List */ + if ((new_elt->u.str == NULL) || + !wbxml_list_insert(lresult, (void *) new_elt, i + 2)) + { + wbxml_value_element_destroy(new_elt); + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + + /* Remove the Attribute Value found in Value Element */ + wbxml_buffer_delete(elt->u.str, index, wbxml_buffer_len(elt->u.str) - index); + } /* if */ + } /* for */ + } /* for */ + } /* if */ + +#endif /* WBXML_ENCODER_USE_STRTBL */ + + + /********************************************************* + * Encode Value Element Buffer + */ + + ret = wbxml_encode_value_element_list(encoder, lresult); + + /* Clean-up */ + wbxml_list_destroy(lresult, wbxml_value_element_destroy_item); + + return ret; +} + + +/** + * @brief Encode a WBXML Value Element List + * @param encoder The WBXML Encoder + * @param list The Value Element list + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError wbxml_encode_value_element_list(WBXMLEncoder *encoder, WBXMLList *list) +{ + WBXMLValueElement *elt = NULL; + WB_ULONG i = 0; + WBXMLError ret = WBXML_OK; + + if (encoder == NULL) + return WBXML_ERROR_INTERNAL; + + if (list == NULL) + return WBXML_OK; + + for (i = 0; i < wbxml_list_len(list); i++) { + if ((elt = (WBXMLValueElement *) wbxml_list_get(list, i)) == NULL) + continue; + + switch (elt->type) { + case WBXML_VALUE_ELEMENT_STRING: + /* Inline String */ + if (wbxml_buffer_len(elt->u.str) > 0) { + if ((ret = wbxml_encode_inline_string(encoder, elt->u.str)) != WBXML_OK) + return ret; + } + break; + +#if defined( WBXML_ENCODER_USE_STRTBL ) + case WBXML_VALUE_ELEMENT_TABLEREF: + /* String Table Reference */ + if ((ret = wbxml_encode_tableref(encoder, elt->u.index)) != WBXML_OK) + return ret; + break; +#endif /* WBXML_ENCODER_USE_STRTBL */ + + case WBXML_VALUE_ELEMENT_EXTENSION: + /* Encode Extension Token */ + if ((ret = wbxml_encode_inline_integer_extension_token(encoder, WBXML_EXT_T_0, elt->u.ext->wbxmlToken)) != WBXML_OK) + return ret; + break; + + case WBXML_VALUE_ELEMENT_OPAQUE: + /** @todo Opaque */ + break; + + case WBXML_VALUE_ELEMENT_ATTR_TOKEN: + /* Attribute Value Token */ + if ((ret = wbxml_encode_attr_token(encoder, elt->u.attr->wbxmlToken, elt->u.attr->wbxmlCodePage)) != WBXML_OK) + return ret; + break; + + default: + return WBXML_ERROR_INTERNAL; + } + } + + return WBXML_OK; +} + + +/** + * @brief Encode a WBXML Literal Attribute Start + * @param encoder The WBXML Encoder + * @param attr The literal attr name to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note attrStart = (LITERAL index) + * index = mb_u_int32 + */ +static WBXMLError wbxml_encode_attr_start_literal(WBXMLEncoder *encoder, const WB_UTINY *attr) +{ +#if defined( WBXML_ENCODER_USE_STRTBL ) + WBXMLStringTableElement *elt = NULL; + WBXMLBuffer *buff = NULL; + WB_ULONG index = 0; + WB_BOOL added = FALSE; + + /* If String Table generation is disabled, we can't generate this Literal */ + if (!encoder->use_strtbl) + return WBXML_ERROR_STRTBL_DISABLED; + + /* Add tag in String Table */ + if (((buff = wbxml_buffer_create(attr, WBXML_STRLEN(attr), WBXML_STRLEN(attr))) == NULL) || + ((elt = wbxml_strtbl_element_create(buff, FALSE)) == NULL) || + (!wbxml_strtbl_add_element(encoder, elt, &index, &added))) + { + wbxml_strtbl_element_destroy(elt); + wbxml_buffer_destroy(buff); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* If already exists in String Table: clean-up */ + if (!added) + wbxml_strtbl_element_destroy(elt); + + /* Encode LITERAL index */ + if ((!wbxml_buffer_append_char(encoder->output, WBXML_LITERAL)) || + (!wbxml_buffer_append_mb_uint_32(encoder->output, index))) + { + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + return WBXML_OK; +#else + /* No String Table Support */ + return WBXML_ERROR_STRTBL_DISABLED; +#endif /* WBXML_ENCODER_USE_STRTBL */ +} + + +/** + * @brief Encode a WBXML Attribute Token + * @param encoder The WBXML Encoder + * @param token The WBXML Attribute Token to encode + * @param page The WBXML CodePage for this Token + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note attrStart = ([switchPage] ATTRSTART) + * switchPage = SWITCH_PAGE pageindex + * pageindex = u_int8 + * + * And: attrValue = ([switchPage] ATTRVALUE) + */ +static WBXMLError wbxml_encode_attr_token(WBXMLEncoder *encoder, WB_UTINY token, WB_UTINY page) +{ + /* Switch Page if needed */ + if (encoder->attrCodePage != page) + { + if ((!wbxml_buffer_append_char(encoder->output, WBXML_SWITCH_PAGE)) || + (!wbxml_buffer_append_char(encoder->output, page))) + { + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + encoder->attrCodePage = page; + } + + /* Add Token */ + if (!wbxml_buffer_append_char(encoder->output, token)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} + + +/** + * @brief Encode a WBXML Inline String + * @param encoder The WBXML Encoder + * @param str The String to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError wbxml_encode_inline_string(WBXMLEncoder *encoder, WBXMLBuffer *str) +{ + /* Add STR_I */ + if (!wbxml_buffer_append_char(encoder->output, WBXML_STR_I)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add String */ + if (!wbxml_buffer_append(encoder->output, str)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add Null Termination */ + if (!wbxml_buffer_append_char(encoder->output, WBXML_STR_END)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} + + +/** + * @brief Encode a WBXML Inline Integer Extension Token + * @param encoder The WBXML Encoder + * @param ext Extension Type (WBXML_EXT_T_0, WBXML_EXT_T_1 or WBXML_EXT_T_2) + * @param value The Extension Token Value + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note (WBXML 1.3 - 5.8.4.2) Inline integrer extension token = EXT_T* mb_u_int32 + */ +static WBXMLError wbxml_encode_inline_integer_extension_token(WBXMLEncoder *encoder, WB_UTINY ext, WB_UTINY value) +{ + /* Add EXT_T* */ + if (!wbxml_buffer_append_char(encoder->output, ext)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add Value */ + if (!wbxml_buffer_append_mb_uint_32(encoder->output, (WB_ULONG) value)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} + + +#if 0 +/** + * @brief Encode a WBXML Entity + * @param encoder The WBXML Encoder + * @param value The Entity to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note (WBXML 1.3 - 5.8.4.3) entity = ENTITY entcode + * entcode = mb_u_int32 + */ +static WBXMLError wbxml_encode_entity(WBXMLEncoder *encoder, WB_ULONG value) +{ + /* Add ENTITY */ + if (!wbxml_buffer_append_char(encoder->output, WBXML_ENTITY)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add entcode */ + if (!wbxml_buffer_append_mb_uint_32(encoder->output, value)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} +#endif /* 0 */ + + +/** + * @brief Encode a WBXML Opaque, given a Buffer + * @param encoder The WBXML Encoder + * @param buff The Buffer to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note This function is simple a wrapper to wbxml_encode_opaque_data() + */ +static WBXMLError wbxml_encode_opaque(WBXMLEncoder *encoder, WBXMLBuffer *buff) +{ + return wbxml_encode_opaque_data(encoder, wbxml_buffer_get_cstr(buff), wbxml_buffer_len(buff)); +} + + +/** + * @brief Encode a WBXML Opaque + * @param encoder The WBXML Encoder + * @param data The data to encode + * @param data_len The data length to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note opaque = OPAQUE length *byte + * length = mb_u_int32 + */ +static WBXMLError wbxml_encode_opaque_data(WBXMLEncoder *encoder, WB_UTINY *data, WB_ULONG data_len) +{ + /* Add WBXML_OPAQUE */ + if (!wbxml_buffer_append_char(encoder->output, WBXML_OPAQUE)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add Length */ + if (!wbxml_buffer_append_mb_uint_32(encoder->output, data_len)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add Buffer */ + if (!wbxml_buffer_append_data(encoder->output, data, data_len)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} + + +#if defined( WBXML_ENCODER_USE_STRTBL ) +/** + * @brief Encode a WBXML String Table Reference + * @param encoder The WBXML Encoder + * @param offset The String Table offset + * @return WBXML_OK if encoding is OK, an error code otherwise + * @note tableref = STR_T index + */ +static WBXMLError wbxml_encode_tableref(WBXMLEncoder *encoder, WB_ULONG offset) +{ + /* Add WBXML_STR_T */ + if (!wbxml_buffer_append_char(encoder->output, WBXML_STR_T)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add String */ + if (!wbxml_buffer_append_mb_uint_32(encoder->output, offset)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} +#endif /* WBXML_ENCODER_USE_STRTBL */ + + +/** + * @brief Create a WBXMLValueElement structure + * @return The newly created WBXMLValueElement structure, or NULL if not enough memory + */ +static WBXMLValueElement *wbxml_value_element_create(void) +{ + WBXMLValueElement *elt = NULL; + + if ((elt = (WBXMLValueElement*) wbxml_malloc(sizeof(WBXMLValueElement))) == NULL) + return NULL; + + elt->type = WBXML_VALUE_ELEMENT_STRING; + elt->u.str = NULL; + + return elt; +} + + +/** + * @brief Destroy a WBXMLValueElement structure + * @param elt The WBXMLValueElement structure to destroy + */ +static void wbxml_value_element_destroy(WBXMLValueElement *elt) +{ + if (elt == NULL) + return; + + switch (elt->type) { + case WBXML_VALUE_ELEMENT_STRING: + wbxml_buffer_destroy(elt->u.str); + break; + case WBXML_VALUE_ELEMENT_OPAQUE: + wbxml_buffer_destroy(elt->u.buff); + break; + default: + /* Nothing to destroy */ + break; + } + + wbxml_free((void*) elt); +} + + +/** + * @brief Destroy a WBXMLValueElement structure (for wbxml_list_destroy() function) + * @param elt The WBXMLValueElement structure to destroy + */ +static void wbxml_value_element_destroy_item(void *elt) +{ + wbxml_value_element_destroy((WBXMLValueElement *) elt); +} + + +/** + * @brief Encode an encapsulated WBXML Tree to WBXML + * @param encoder [in] The WBXML Encoder + * @param tree [in] The WBXML Tree to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError wbxml_encode_tree(WBXMLEncoder *encoder, WBXMLTree *tree) +{ + WBXMLEncoder *new_encoder = NULL; + WB_UTINY *wbxml = NULL; + WB_ULONG wbxml_len = 0; + WBXMLError ret = WBXML_OK; + + if ((new_encoder = encoder_duplicate(encoder)) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Set Tree */ + new_encoder->tree = tree; + + /* Encode to WBXML */ + if ((ret = wbxml_encoder_encode_tree_to_wbxml(new_encoder, &wbxml, &wbxml_len)) != WBXML_OK) { + wbxml_encoder_destroy(new_encoder); + return ret; + } + + /* Clean-up */ + wbxml_encoder_destroy(new_encoder); + + /* Add WBXML_OPAQUE */ + if (!wbxml_buffer_append_char(encoder->output, WBXML_OPAQUE)) { + wbxml_free(wbxml); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Add Length */ + if (!wbxml_buffer_append_mb_uint_32(encoder->output, wbxml_len)) { + wbxml_free(wbxml); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Append wbxml to output */ + if (!wbxml_buffer_append_data(encoder->output, wbxml, wbxml_len)) { + wbxml_free(wbxml); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Clean-up */ + wbxml_free(wbxml); + + return WBXML_OK; +} + + +/**************************************** + * Language Specific Encoding Functions + */ + +#if ( defined( WBXML_SUPPORT_SI ) || defined( WBXML_SUPPORT_EMN ) ) + +/******************* + * SI 1.0 / EMN 1.0 + */ + +/** + * @brief Encode SI %Datetime attribute value + * @param encoder The WBXML Encoder + * @param buffer The %Datetime value to encode + * @return WBXML_OK if encoded, another error code otherwise + * @note [SI] - 8.2.2. Encoding of %Datetime + */ +static WBXMLError wbxml_encode_datetime(WBXMLEncoder *encoder, WB_UTINY *buffer) +{ + WBXMLBuffer *tmp = NULL; + WB_ULONG i = 0; + WB_UTINY ch = 0; + WBXMLError ret = WBXML_OK; + + + if ((tmp = wbxml_buffer_create_from_cstr(buffer)) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Remove non-digit characters */ + while (i < wbxml_buffer_len(tmp)) { + /* Get char */ + if (!wbxml_buffer_get_char(tmp, i, &ch)) { + wbxml_buffer_destroy(tmp); + return WBXML_ERROR_INTERNAL; + } + + if (!WBXML_ISDIGIT(ch)) { + if ((ch != 'T') && (ch != 'Z') && (ch != '-') && (ch != ':')) { + wbxml_buffer_destroy(tmp); + return WBXML_ERROR_BAD_DATETIME; + } + + /* Remove it */ + wbxml_buffer_delete(tmp, i, 1); + } + else + i++; + } + + /* Convert Ascii to Binary buffer */ + wbxml_buffer_hex_to_binary(tmp); + + /* Remove trailing zero */ + wbxml_buffer_remove_trailing_zeros(&tmp); + + /* Encode it to Opaque */ + ret = wbxml_encode_opaque(encoder, tmp); + + wbxml_buffer_destroy(tmp); + + return ret; +} + +#endif /* WBXML_SUPPORT_SI || WBXML_SUPPORT_EMN */ + + +#if defined( WBXML_SUPPORT_WV ) + +/******************* + * WV 1.1 / WV 1.2 + */ + +/** + * @brief Encode a Wireless-Village Content buffer + * @param encoder The WBXML Encoder + * @param buffer The buffer to encode + * @return WBXML_OK if encoded, WBXML_NOT_ENCODED if not encoded, another error code otherwise + * @note This function encodes a Specific WV Data Type content, or an exact Extension Token. + * If not found, this is not encoded... and it will be encoded latter as an Inline String + * in wbxml_encode_value_element_buffer(). We don't deal here if this buffer CONTAINS + * Extension Tokens. + */ +static WBXMLError wbxml_encode_wv_content(WBXMLEncoder *encoder, WB_UTINY *buffer) +{ + const WBXMLExtValueEntry *ext = NULL; + WBXMLWVDataType data_type = WBXML_WV_DATA_TYPE_STRING; + /* WB_ULONG ucs4_ch = 0; */ + + /* + * Specific Data Type Elements: + * + * Boolean: + * Acceptance (0x00 / 0x05) + * InUse (0x00 / 0x18) + * Poll (0x00 / 0x21) + * AllFunctionsRequest (0x01 / 0x06) + * CapabilityRequest (0x01 / 0x0B) + * CompletionFlag (0x01 / 0x34) + * ReceiveList (0x01 / 0x36) [WV 1.2] + * AnyContent (0x03 / 0x09) + * DefaultList (0x04 / 0x0B) + * Auto-Subscribe (0x04 / 0x1E) [WV 1.2] + * DeliveryReport (0x06 / 0x08) + * JoinGroup (0x07 / 0x21) + * JoinedRequest (0x07 / 0x10) + * SubscribeNotification (0x07 / 0x22) + * CIR (0x09 / 0x05) [WV 1.2] + * + * Integer: + * Code (0x00 / 0x0B) + * ContentSize (0x00 / 0x0F) + * MessageCount (0x00 / 0x1A) + * Validity (0x00 / 0x3C) + * KeepAliveTime (0x01 / 0x1C) + * SearchFindings (0x01 / 0x25) + * SearchID (0x01 / 0x26) + * SearchIndex (0x01 / 0x27) + * SearchLimit (0x01 / 0x28) + * TimeToLive (0x01 / 0x32) + * AcceptedCharSet (0x03 / 0x05) + * AcceptedContentLength (0x03 / 0x06) + * MultiTrans (0x03 / 0x0C) + * ParserSize (0x03 / 0x0D) + * ServerPollMin (0x03 / 0x0E) + * TCPPort (0x03 / 0x12) + * UDPPort (0x03 / 0x13) + * HistoryPeriod (0x09 / 0x08) [WV 1.2] + * MaxWatcherList (0x09 / 0x0A) [WV 1.2] + * + * Date and Time: + * DateTime (0x00 / 0x11) + * DeliveryTime (0x06 / 0x1A) + * + * Binary: + * ContentData (0x00 / 0x0D) (only if we have a: "BASE64" associated) + */ + + /**************************************** + * Get the Data Type of Current Element + */ + + if (encoder->current_tag != NULL) + { + switch (encoder->current_tag->wbxmlCodePage) { + case 0x00: + /* Code Page: 0x00 */ + switch (encoder->current_tag->wbxmlToken) { + case 0x05: /* Acceptance */ + case 0x18: /* InUse */ + case 0x21: /* Poll */ + /* BOOLEAN */ + data_type = WBXML_WV_DATA_TYPE_BOOLEAN; + break; + case 0x0B: /* Code */ + case 0x0F: /* ContentSize */ + case 0x1A: /* MessageCount */ + case 0x3C: /* Validity */ + /* INTEGER */ + data_type = WBXML_WV_DATA_TYPE_INTEGER; + break; + case 0x11: /* DateTime */ + /* DATE_AND_TIME */ + data_type = WBXML_WV_DATA_TYPE_DATE_AND_TIME; + break; + case 0x0D: /* ContentData */ + /* BINARY */ + /** @todo Check if we have a: "BASE64" associated */ + /* + if (base64_encoded) + data_type = WBXML_WV_DATA_TYPE_BINARY; + else + */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + case 0x01: + /* Code Page: 0x01 */ + switch (encoder->current_tag->wbxmlToken) { + case 0x06: /* AllFunctionsRequest */ + case 0x0B: /* CapabilityRequest */ + case 0x34: /* CompletionFlag */ + case 0x36: /* ReceiveList */ + /* BOOLEAN */ + data_type = WBXML_WV_DATA_TYPE_BOOLEAN; + break; + case 0x1C: /* KeepAliveTime */ + case 0x25: /* SearchFindings */ + case 0x26: /* SearchID */ + case 0x27: /* SearchIndex */ + case 0x28: /* SearchLimit */ + case 0x32: /* TimeToLive */ + /* INTEGER */ + data_type = WBXML_WV_DATA_TYPE_INTEGER; + break; + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + case 0x03: + /* Code Page: 0x03 */ + switch (encoder->current_tag->wbxmlToken) { + case 0x09: /* AnyContent */ + /* BOOLEAN */ + data_type = WBXML_WV_DATA_TYPE_BOOLEAN; + break; + case 0x05: /* AcceptedCharSet */ + case 0x06: /* AcceptedContentLength */ + case 0x0C: /* MultiTrans */ + case 0x0D: /* ParserSize */ + case 0x0E: /* ServerPollMin */ + case 0x12: /* TCPPort */ + case 0x13: /* UDPPort */ + /* INTEGER */ + data_type = WBXML_WV_DATA_TYPE_INTEGER; + break; + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + case 0x04: + /* Code Page: 0x04 */ + switch (encoder->current_tag->wbxmlToken) { + case 0x0B: /* DefaultList */ + case 0x1E: /* Auto-Subscribe */ + /* BOOLEAN */ + data_type = WBXML_WV_DATA_TYPE_BOOLEAN; + break; + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + case 0x06: + /* Code Page: 0x06 */ + switch (encoder->current_tag->wbxmlToken) { + case 0x08: /* DeliveryReport */ + /* BOOLEAN */ + data_type = WBXML_WV_DATA_TYPE_BOOLEAN; + break; + case 0x1A: /* DeliveryTime */ + /* DATE AND TIME */ + data_type = WBXML_WV_DATA_TYPE_DATE_AND_TIME; + break; + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + case 0x07: + /* Code Page: 0x07 */ + switch (encoder->current_tag->wbxmlToken) { + case 0x21: /* JoinGroup */ + case 0x10: /* JoinedRequest */ + case 0x22: /* SubscribeNotification */ + /* BOOLEAN */ + data_type = WBXML_WV_DATA_TYPE_BOOLEAN; + break; + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + case 0x09: + /* Code Page: 0x09 */ + switch (encoder->current_tag->wbxmlToken) { + case 0x05: /* CIR */ + /* BOOLEAN */ + data_type = WBXML_WV_DATA_TYPE_BOOLEAN; + break; + case 0x08: /* HistoryPeriod */ + case 0x0A: /* MaxWatcherList */ + /* INTEGER */ + data_type = WBXML_WV_DATA_TYPE_INTEGER; + break; + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + default: + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + } + + + /**************************************** + * Encode, given the Data Type + */ + + switch (data_type) { + case WBXML_WV_DATA_TYPE_INTEGER: + /* Integer: Encode it */ + return wbxml_encode_wv_integer(encoder, buffer); + break; + case WBXML_WV_DATA_TYPE_DATE_AND_TIME: + /* Date and time can be encoded as OPAQUE data or as a string as specified in [ISO8601]. */ + return wbxml_encode_wv_datetime(encoder, buffer); + break; + case WBXML_WV_DATA_TYPE_BINARY: + /** @todo Binary Encoding !! */ + break; + case WBXML_WV_DATA_TYPE_BOOLEAN: + /* Booleans are handled by the "T" and "F" extension tokens */ + case WBXML_WV_DATA_TYPE_STRING: + /* Check if this buffer is an EXACT Extension Token */ + if ((ext = wbxml_tables_get_ext_from_xml(encoder->lang, buffer)) != NULL) + return wbxml_encode_inline_integer_extension_token(encoder, WBXML_EXT_T_0, ext->wbxmlToken); + else { + if (WBXML_STRLEN(buffer) == 1) + { + /** + * @todo [OMA WV 1.1] - 6.1 : A single character can be encoded as ENTITY (0x02) followed + * by a mb_u_int32 containing the entity number. + */ + + /* + if (convert_char_to_ucs4(*buffer, &ucs4_ch)) + return wbxml_encode_entity(encoder, ucs4_ch); + */ + } + + /* Else: noting encoded... this will be latter as an inline string */ + } + break; + default: + /* Hu ? */ + break; + } + + return WBXML_NOT_ENCODED; +} + + +/** + * @brief Encode a Wireless-Village Integer + * @param encoder The WBXML Encoder + * @param buffer The buffer that contains the string representation of the integer to encode + * @return WBXML_OK if OK, another error code otherwise + */ +static WBXMLError wbxml_encode_wv_integer(WBXMLEncoder *encoder, WB_UTINY *buffer) +{ + WB_UTINY octets[4]; + WB_ULONG the_int = 0, start = 0; + WB_LONG i = 0; + + if ((encoder == NULL) || (buffer == NULL)) + return WBXML_ERROR_INTERNAL; + + if (buffer[1] == 'x' || buffer[1] == 'X') { + the_int = (WB_ULONG) strtol((const WB_TINY *) buffer , NULL , 16); + } else { + the_int = (WB_ULONG) atol((const WB_TINY *) buffer); + } + + + for (i = 3; the_int > 0 && i >= 0; i--) { + octets[i] = (WB_UTINY)(the_int & 0xff); + the_int >>= 8; + } + + start = i + 1; + + /* Add WBXML_OPAQUE */ + if (!wbxml_buffer_append_char(encoder->output, WBXML_OPAQUE)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add Integer Length */ + if (!wbxml_buffer_append_mb_uint_32(encoder->output, 4 - start)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add Integer */ + if (!wbxml_buffer_append_data(encoder->output, octets + start, (WB_UTINY)(4 - start))) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} + + +/** + * @brief Encode inline WV Date and Time content value + * @param encoder The WBXML Encoder + * @param buffer The ISO 8601 Date and Time value to encode + * @return WBXML_OK if encoded, another error code otherwise + * @note [WV] - 6.6 Date and Time + * @note + * Encoded Format: + * - ISO 8601 string (see expected format) + * + * Expected Format (ISO 8601): + * 20011019T0950Z + * 20011019T095031Z + * 2001-10-19T09:50:31Z (with number seperators) + * 2001-10-19T09:50:31+01:00 (with explicit positive time zone) + * 2001-10-19T09:50:31+05:00 (with explicit negative time zone) + */ +static WBXMLError wbxml_encode_wv_datetime_inline(WBXMLEncoder *encoder, WB_UTINY *buffer) +{ + WBXMLError result = WBXML_OK; + WBXMLBuffer *tmp = NULL; + + /* Create temp Buffer */ + if ((tmp = wbxml_buffer_create_from_cstr(buffer)) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Add buffer to encoder */ + result = wbxml_encode_inline_string(encoder, tmp); + + /* Cleanup buffer */ + wbxml_buffer_destroy(tmp); + + return result; +} + + +/** + * @brief Encode opaque WV Date and Time content value + * @param encoder The WBXML Encoder + * @param buffer The ISO 8601 Date and Time value to encode + * @return WBXML_OK if encoded, another error code otherwise + * @note [WV] - 6.6 Date and Time + * @note + * Encoded Format: (6 octets) + * - The first 2 bits are reserved, and both must be 0. + * - Year is encoded by 12 bits (0 to 4095) + * - Month is encoded by 4 bits (1 to 12) + * - Day is encoded by 5 bits (1 to 31) + * - Hour is encoded by 5 bits (0 to 23) + * - Minute is encoded by 6 bits (0 to 59) + * - Second is encoded by 6 bits (0 to 59) + * - Time zone is encoded in 1 byte [ISO8601]. + * + * eg: + * Binary: 00 011111010001 1010 10011 01001 110010 011111 01011010 + * Octets: (-------)(-------)(--------)(-------)(-------) (------) + * + * Expected Format (ISO 8601): + * 20011019T0950 (missing seconds and time zone) + * 20011019T0950Z (missing seconds) + * 20011019T095031 (missing time zone) + * 20011019T095031Z + * 20011019T095031A (UTC+1) + */ +static WBXMLError wbxml_encode_wv_datetime_opaque(WBXMLEncoder *encoder, WB_UTINY *buffer) +{ + WBXMLError error; + WBXMLBuffer *tmp = NULL; + WB_ULONG i = 0, len = 0; + WB_UTINY ch = 0; + WBXMLError ret = WBXML_OK; + WB_UTINY octets[6]; + WBXMLBuffer *component = NULL; + + /* definitions first ... or some compilers don't like it */ + unsigned int year, month, day, hour, minute, second; + + len = WBXML_STRLEN(buffer); + + /* Create temp Buffer */ + if ((tmp = wbxml_buffer_create_from_cstr(buffer)) == NULL) { + error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + goto error; + } + + /* Check Length */ + if ((len == 13) || (len == 14)) { + /* This is illegal but we can tolerate datetimes + * which forget the seconds. + */ + WBXML_WARNING((WBXML_CONV, "The WV datetime %s is missing the seconds.", buffer)); + if (len == 13) { + wbxml_buffer_append_cstr(tmp, "00"); + } else { + wbxml_buffer_insert_cstr(tmp, (WB_UTINY *) "00", 13); + } + len = wbxml_buffer_len(tmp); + } + if ((len != 15) && (len != 16)) { + WBXML_ERROR((WBXML_CONV, "The length of a WV datetime must be 15 or 16.")); + error = WBXML_ERROR_WV_DATETIME_FORMAT; + goto error; + } + + /* Check position of 'T' */ + if (*(buffer+8) != 'T') { + WBXML_ERROR((WBXML_CONV, "The 9th character of a WV datetime must be 'T'.")); + error = WBXML_ERROR_WV_DATETIME_FORMAT; + goto error; + } + + /* Check position of time zone */ + if (len == 16) { + if (!wbxml_buffer_get_char(tmp, 15, &ch)) { + error = WBXML_ERROR_INTERNAL; + goto error; + } + if (ch < 'A' || ch == 'J' || ch > 'Z') { + WBXML_ERROR((WBXML_CONV, "If the length of a WV datetime is 16 then the last character must be the time zone.")); + error = WBXML_ERROR_WV_DATETIME_FORMAT; + goto error; + } + + /* There is a time zone. */ + octets[5] = ch; + + /* delete time zone */ + wbxml_buffer_delete(tmp, 15, 1); + } else { + /* There is no time zone. */ + octets[5] = 0; + } + + /* delete 'T' */ + wbxml_buffer_delete(tmp, 8, 1); + + /* Check if you have only digits characters */ + while (i < wbxml_buffer_len(tmp)) { + /* Get char */ + if (!wbxml_buffer_get_char(tmp, i, &ch)) { + error = WBXML_ERROR_INTERNAL; + goto error; + } + + if (!WBXML_ISDIGIT(ch)) { + error = WBXML_ERROR_WV_DATETIME_FORMAT; + goto error; + } + else + i++; + } + + WBXML_DEBUG((WBXML_CONV, "Starting WV datetime conversion ...")); + + /* Set Year */ + component = wbxml_buffer_duplicate(tmp); + if (!component) { + error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + goto error; + } + wbxml_buffer_delete(component, 4, 10); + year = strtoul((const char *)wbxml_buffer_get_cstr(component), NULL, 10); + wbxml_buffer_destroy(component); + octets[0] = (WB_UTINY) ((year & 0xfc0) >> 6); /* 6 bits */ + octets[1] = (WB_UTINY) (year & 0x3f); /* 6 bits */ + + /* Set Month */ + component = wbxml_buffer_duplicate(tmp); + if (!component) { + error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + goto error; + } + wbxml_buffer_delete(component, 0, 4); + wbxml_buffer_delete(component, 2, 8); + month = strtoul((const char *)wbxml_buffer_get_cstr(component), NULL, 10); + wbxml_buffer_destroy(component); + octets[1] <<= 2; + octets[1] += (WB_UTINY) ((month & 0xc) >> 2); /* 2 bits */ + octets[2] = (WB_UTINY) (month & 0x3); /* 2 bits */ + + /* Set Day */ + component = wbxml_buffer_duplicate(tmp); + if (!component) { + error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + goto error; + } + wbxml_buffer_delete(component, 0, 6); + wbxml_buffer_delete(component, 2, 6); + day = strtoul((const char *)wbxml_buffer_get_cstr(component), NULL, 10); + wbxml_buffer_destroy(component); + octets[2] <<= 5; + octets[2] += (WB_UTINY) (day & 0x1f); /* 5 bits */ + + /* Set Hour */ + component = wbxml_buffer_duplicate(tmp); + if (!component) { + error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + goto error; + } + wbxml_buffer_delete(component, 0, 8); + wbxml_buffer_delete(component, 2, 4); + hour = strtoul((const char *)wbxml_buffer_get_cstr(component), NULL, 10); + wbxml_buffer_destroy(component); + octets[2] <<=1; + octets[2] += (WB_UTINY) ((hour & 0x10) >> 4); /* 1 bit */ + octets[3] = (WB_UTINY) (hour & 0xf); /* 4 bits */ + + /* Set Minute */ + component = wbxml_buffer_duplicate(tmp); + if (!component) { + error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + goto error; + } + wbxml_buffer_delete(component, 0, 10); + wbxml_buffer_delete(component, 2, 2); + minute = strtoul((const char *)wbxml_buffer_get_cstr(component), NULL, 10); + wbxml_buffer_destroy(component); + octets[3] <<=4; + octets[3] += (WB_UTINY) ((minute & 0x3c) >> 2); /* 4 bits */ + octets[4] = (WB_UTINY) (minute & 0x3); /* 2 bits */ + + /* Set Second */ + component = wbxml_buffer_duplicate(tmp); + if (!component) { + error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + goto error; + } + wbxml_buffer_delete(component, 0, 12); + second = strtoul((const char *)wbxml_buffer_get_cstr(component), NULL, 10); + wbxml_buffer_destroy(component); + octets[4] <<=6; + octets[4] += (WB_UTINY) (second & 0x3f); /* 6 bits */ + + WBXML_DEBUG((WBXML_CONV, "WV datetime: %x %x %x %x %x %x", octets[0], octets[1], octets[2], octets[3], octets[4], octets[5])); + + /* Encode it to Opaque */ + ret = wbxml_encode_opaque_data(encoder, octets, 6); + + return ret; +error: + if (tmp) + wbxml_buffer_destroy(tmp); + return error; +} + + +/** + * @brief Encode WV Date and Time content value + * @param encoder The WBXML Encoder + * @param buffer The ISO 8601 Date and Time value to encode + * @return WBXML_OK if encoded, another error code otherwise + * @note [WV] - 6.6 Date and Time + * @note This function only decides which kind of datetime + * encoding should be used and calls the appropriate + * function. Please see wbxml_encode_wv_datetime_opaque + * and wbxml_encode_wv_datetime_inline for more details. + * @note Both encoding mechanisms were implemented to be able + * to test the parsing of both encoding scheme. This is + * necessary because other implementations can decide by + * their own which encoding scheme they use. + */ +static WBXMLError wbxml_encode_wv_datetime(WBXMLEncoder *encoder, WB_UTINY *buffer) +{ + WB_BOOL use_inline = FALSE; + WB_ULONG len = WBXML_STRLEN(buffer); + + /* long version of ISO 8601 should be inline encoded */ + if (strchr((WB_TINY *) buffer, '-')) + use_inline = TRUE; + if (strchr((WB_TINY *) buffer, '+')) + use_inline = TRUE; + if (strchr((WB_TINY *) buffer, ':')) + use_inline = TRUE; + + /* timezone Z should be inline encoded */ + if (buffer[len - 1] == 'Z') + use_inline = TRUE; + + if (use_inline) { + WBXML_DEBUG((WBXML_CONV, "WV datetime conversion: INLINE")); + return wbxml_encode_wv_datetime_inline(encoder, buffer); + } else { + WBXML_DEBUG((WBXML_CONV, "WV datetime conversion: OPAQUE")); + return wbxml_encode_wv_datetime_opaque(encoder, buffer); + } +} + +#endif /* WBXML_SUPPORT_WV */ + + +#if defined( WBXML_SUPPORT_DRMREL ) + +/******************* + * DRMREL 1.0 + */ + +/** + * @brief Encode a DRMREL Content buffer + * @param encoder The WBXML Encoder + * @param buffer The buffer to encode + * @return WBXML_OK if encoded, WBXML_NOT_ENCODED if not encoded, another error code otherwise + * @note This function encodes a Specific DRMREL content. + * If not found, this is not encoded... and it will be encoded latter as an Inline String + * in wbxml_encode_value_element_buffer(). + */ +static WBXMLError wbxml_encode_drmrel_content(WBXMLEncoder *encoder, WB_UTINY *buffer) +{ + WB_UTINY *data = NULL; + WB_LONG data_len = 0; + const WBXMLTagEntry *current_tag = NULL; + + if ((encoder->current_text_parent != NULL) && + (encoder->current_text_parent->name != NULL) && + (encoder->current_text_parent->name->type == WBXML_VALUE_TOKEN)) + { + current_tag = encoder->current_text_parent->name->u.token; + } + + if (current_tag != NULL) + { + if ((current_tag->wbxmlCodePage == 0x00) && + (current_tag->wbxmlToken == 0x0C)) + { + /* content: "Encoded in binary format, i.e., no base64 encoding" */ + + /* Decode Base64 */ + if ((data_len = wbxml_base64_decode(buffer, -1, &data)) < 0) + return WBXML_NOT_ENCODED; + + /* Add WBXML_OPAQUE */ + if (!wbxml_buffer_append_char(encoder->output, WBXML_OPAQUE)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add Data Length */ + if (!wbxml_buffer_append_mb_uint_32(encoder->output, (WB_ULONG) data_len)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Add Data */ + if (!wbxml_buffer_append_data(encoder->output, data, data_len)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Free Data */ + wbxml_free(data); + + return WBXML_OK; + } + } + + return WBXML_NOT_ENCODED; +} + +#endif /* WBXML_SUPPORT_DRMREL */ + + +#if defined( WBXML_SUPPORT_OTA_SETTINGS ) + +/******************* + * OTA Settings + */ + +/** + * @brief Encode a OTA ICON as opaque data + * @param encoder The WBXML Encoder + * @param buffer The buffer to encode + * @return WBXML_OK if encoded, WBXML_NOT_ENCODED if not encoded, another error code otherwise + * @note Nokia OTA Settings support for the ICON value in bookmarks. + * + * Nokia introduced a proprietary way of including icons in the old Nokia OTA Settings format when sending bookmarks. + * The encoding is done using base64 encoded images in XML, and encoding it as OPAQUE data in the WBXML. + * The icon is embedded using an PARM element with name ICON. + * + * E.g. the following bookmark (XML) is valid: + * + * + * + * + * + * + * + * + * + * + * + * + * If not found, this is not encoded... and it will be encoded latter as an Inline String in wbxml_encode_value_element_buffer(). + */ +static WBXMLError wbxml_encode_ota_nokia_icon(WBXMLEncoder *encoder, WB_UTINY *buffer) +{ + WBXMLError ret = WBXML_NOT_ENCODED; + + /* Is a VALUE attribute ? */ + if ((encoder->current_tag != NULL) && + (encoder->current_attr->wbxmlCodePage == 0x00) && + (encoder->current_attr->wbxmlToken == 0x11) && + (encoder->current_node && encoder->current_node->attrs)) + { + WBXMLList *attrs = encoder->current_node->attrs; + WB_ULONG index = 0; + WB_ULONG nb_attrs = wbxml_list_len(attrs); + WB_BOOL found = FALSE; + + /* Search for a NAME="ICON" attribute */ + while (!found && (index < nb_attrs)) { + WBXMLAttribute *attr = (WBXMLAttribute*)wbxml_list_get(attrs, index); + + if ((WBXML_STRCMP("NAME", wbxml_attribute_get_xml_name(attr)) == 0) && + (WBXML_STRCMP("ICON", wbxml_attribute_get_xml_value(attr)) == 0)) + { + WB_UTINY *data = NULL; + WB_LONG data_len = 0; + + /* Decode Base64 */ + if ((data_len = wbxml_base64_decode(buffer, -1, &data)) < 0) + return WBXML_NOT_ENCODED; + + /* Encode opaque */ + if ((ret = wbxml_encode_opaque_data(encoder, data, data_len)) != WBXML_OK) + return ret; + + /* Free Data */ + wbxml_free(data); + + found = TRUE; + } + + index++; + } + } + + return ret; +} + +#endif /* WBXML_SUPPORT_OTA_SETTINGS */ + + +#if defined( WBXML_ENCODER_USE_STRTBL ) + +/**************************** + * String Table Functions + */ + +/** + * @brief Create a String Table element + * @param string The WBXMLBuffer containing the String + * @param is_stat If set to TRUE, this Buffer won't be destroyed in wbxml_strtbl_element_destroy() function + * @return The newly created String Table Element, or NULL if not enought memory + */ +static WBXMLStringTableElement *wbxml_strtbl_element_create(WBXMLBuffer *string, WB_BOOL is_stat) +{ + WBXMLStringTableElement *elt = NULL; + + if ((elt = (WBXMLStringTableElement *) wbxml_malloc(sizeof(WBXMLStringTableElement))) == NULL) + return NULL; + + elt->string = string; + elt->offset = 0; + elt->count = 0; + elt->stat = is_stat; + + return elt; +} + + +/** + * @brief Destroy a String Table element + * @param element The element to destroy + */ +static void wbxml_strtbl_element_destroy(WBXMLStringTableElement *element) +{ + if (element == NULL) + return; + + if (!element->stat) + wbxml_buffer_destroy(element->string); + + wbxml_free(element); +} + + +/** + * @brief Destroy a String Table element (for wbxml_list_destroy()) + * @param element The element to destroy + */ +static void wbxml_strtbl_element_destroy_item(void *element) +{ + wbxml_strtbl_element_destroy((WBXMLStringTableElement *) element); +} + + +/** + * @brief Initialize the String Table + * @param encoder The WBXML Encoder + * @param root The root element of LibXML Tree + */ +static WBXMLError wbxml_strtbl_initialize(WBXMLEncoder *encoder, WBXMLTreeNode *root) +{ + WBXMLList *strings = NULL, *one_ref = NULL; + WBXMLError ret; + + if ((strings = wbxml_list_create()) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Collect all Strings: + * [out] 'strings' is the list of pointers to WBXMLBuffer. This Buffers must not be freed. + */ + wbxml_strtbl_collect_strings(encoder, root, strings); + + /* Insert, in String Table, Strings that are referenced more than one time + * [out] 'strings' is NULL + * 'one_ref' is the list of strings referenced only ONE time (list of WBXMLStringTableElement*) + * Strings referenced more than one time are added to String Table + */ + if ((ret = wbxml_strtbl_check_references(encoder, &strings, &one_ref, TRUE)) != WBXML_OK) { + wbxml_list_destroy(strings, NULL); + return ret; + } + + /* 'strings' is destroyed after call of wbxml_strtbl_check_references() */ + + /* Split Strings refered only one time in Words + * [out] 'strings' is the list of words. This words (WBXMLBuffer) must be freed + */ + if ((ret = wbxml_strtbl_collect_words(one_ref, &strings)) != WBXML_OK) { + wbxml_list_destroy(one_ref, wbxml_strtbl_element_destroy_item); + return ret; + } + + /* Destroy References List */ + wbxml_list_destroy(one_ref, wbxml_strtbl_element_destroy_item); + one_ref = NULL; + + /* Keep Strings referenced more than one time */ + if (strings != NULL) + wbxml_strtbl_check_references(encoder, &strings, &one_ref, FALSE); + + /* 'strings' is destroyed after call of wbxml_strtbl_check_references() */ + + /* Cleanup */ + wbxml_list_destroy(one_ref, wbxml_strtbl_element_destroy_item); + + return WBXML_OK; +} + + +/** + * @brief Collect Strings in XML Document (in Text Content and Attribute Values) + * @param encoder [in] The WBXML Encoder + * @param node [in] The current element node of LibXML Tree + * @param strings [out] List of WBXMLBuffer buffers corresponding to Collected Strings + */ +static void wbxml_strtbl_collect_strings(WBXMLEncoder *encoder, WBXMLTreeNode *node, WBXMLList *strings) +{ + const WBXMLAttrEntry *attr_entry = NULL; + WBXMLAttribute *attr = NULL; + WB_ULONG i = 0; + WB_UTINY *value_left = NULL; + + switch (node->type) + { + case WBXML_TREE_TEXT_NODE: + /* Ignore blank nodes */ + if (wbxml_buffer_contains_only_whitespaces(node->content)) + break; + + /** @todo Shrink / Strip Blanks */ + + /* Only add this string if it is big enought */ + if (wbxml_buffer_len(node->content) > WBXML_ENCODER_STRING_TABLE_MIN) { + wbxml_list_append(strings, node->content); + WBXML_DEBUG((WBXML_ENCODER, "Strtbl - Collecting String: %s", wbxml_buffer_get_cstr(node->content))); + } + break; + + case WBXML_TREE_ELEMENT_NODE: + /* Collect strings in Attributes Values too */ + if (node->attrs != NULL) { + for (i = 0; i < wbxml_list_len(node->attrs); i++) { + /* Get attribute */ + attr = wbxml_list_get(node->attrs, i); + + /* Only add this string if it is big enought */ + if (wbxml_buffer_len(attr->value) > WBXML_ENCODER_STRING_TABLE_MIN) { + /* This mustn't be a tokenisable Attribute Start */ + attr_entry = wbxml_tables_get_attr_from_xml(encoder->lang, + (WB_UTINY *) wbxml_attribute_get_xml_name(attr), + (WB_UTINY *) wbxml_attribute_get_xml_value(attr), + &value_left); + + /* - If attr_entry is NULL: no Attribute Start found + * - If attr_entry is not NULL: and Attribute Start is found, but it can be the one with + * no Attribute Value associated. So just check that the 'value_left' is the same than + * the attribute value we where searching for + */ + if ((attr_entry == NULL) || ((attr_entry != NULL) && (value_left == (WB_UTINY *) wbxml_attribute_get_xml_value(attr)))) + { + /* It mustn't contain a tokenisable Attribute Value */ + if (!wbxml_tables_contains_attr_value_from_xml(encoder->lang, + (WB_UTINY *) wbxml_attribute_get_xml_value(attr))) + { + wbxml_list_append(strings, attr->value); + WBXML_DEBUG((WBXML_ENCODER, "Strtbl - Collecting String: %s", wbxml_buffer_get_cstr(attr->value))); + } + } + } + } + } + break; + + default: + /* NOOP */ + break; + } + + if (node->children != NULL) + wbxml_strtbl_collect_strings(encoder, node->children, strings); + + if (node->next != NULL) + wbxml_strtbl_collect_strings(encoder, node->next, strings); +} + + +/** + * @brief Split Strings into Words + * @param elements [in] List of String Table Elements to split + * @param result [out] Resulting list of Words + * @return WBXML_OK is no error, another error code otherwise + */ +static WBXMLError wbxml_strtbl_collect_words(WBXMLList *elements, WBXMLList **result) +{ + WBXMLStringTableElement *elt = NULL; + WBXMLList *list = NULL, *temp_list = NULL; + WBXMLBuffer *word = NULL; + WB_ULONG i = 0; + + *result = NULL; + + for (i = 0; i < wbxml_list_len(elements); i++) + { + elt = (WBXMLStringTableElement *) wbxml_list_get(elements, i); + + if (list == NULL) { + if ((list = wbxml_buffer_split_words(elt->string)) == NULL) { + wbxml_list_destroy(list, wbxml_buffer_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } else { + if ((temp_list = wbxml_buffer_split_words(elt->string)) == NULL) { + wbxml_list_destroy(list, wbxml_buffer_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + while ((word = wbxml_list_extract_first(temp_list)) != NULL) { + if (!wbxml_list_append(list, word)) { + wbxml_buffer_destroy(word); + wbxml_list_destroy(temp_list, wbxml_buffer_destroy_item); + wbxml_list_destroy(list, wbxml_buffer_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + + wbxml_list_destroy(temp_list, NULL); + } + } + + *result = list; + + return WBXML_OK; +} + + +/** + * @brief Append the String Table to result Buffer + * @param buff The Buffer to append the String Table to + * @param strstbl The String Table to append + */ +static WBXMLError wbxml_strtbl_construct(WBXMLBuffer *buff, WBXMLList *strstbl) +{ + WBXMLStringTableElement *elt = NULL; + WB_ULONG i = 0; + + if ((buff == NULL) || (strstbl == NULL)) + return WBXML_ERROR_BAD_PARAMETER; + + for (i = 0; i < wbxml_list_len(strstbl); i++) + { + if ((elt = wbxml_list_get(strstbl, i)) == NULL) + continue; + + if (!wbxml_buffer_append(buff, elt->string)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + if (!wbxml_buffer_append_char(buff, WBXML_STR_END)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + return WBXML_OK; +} + + +/** + * @brief Check strings that have multiple references, add them to string table + * and return strings that have only one reference + * @param encoder The WBXML Encoder + * @param strings The List of Strings to check (List of WBXMLBuffer) : This list is freed by this function + * @param one_ref List of strings that have only one reference (List of WBXMLStringTableElement) + * @param stat_buff If set to TRUE, Buffers referenced by 'strings' must NOT be destroyed. + * @return WBXML_OK if no error, another error code otherwise + * @warning All elements of 'strings' list are removed from this list + */ +static WBXMLError wbxml_strtbl_check_references(WBXMLEncoder *encoder, WBXMLList **strings, WBXMLList **one_ref, WB_BOOL stat_buff) +{ + WBXMLList *referenced = NULL, *result = NULL; + WBXMLBuffer *string = NULL; + WBXMLStringTableElement *ref = NULL; + WB_ULONG j = 0; + WB_BOOL added = FALSE; + + if ((strings == NULL) || (one_ref == NULL)) + return WBXML_ERROR_INTERNAL; + + *one_ref = NULL; + + /* Create list of String References */ + if ((referenced = wbxml_list_create()) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + + /********************* + * Count References + */ + + while (wbxml_list_len(*strings) > 0) + { + string = (WBXMLBuffer *) wbxml_list_extract_first(*strings); + + /* Check if we have already found this String */ + for (j = 0; j < wbxml_list_len(referenced); j++) + { + ref = (WBXMLStringTableElement *) wbxml_list_get(referenced, j); + + if (wbxml_buffer_compare(ref->string, string) == 0) + { + if (!stat_buff) + wbxml_buffer_destroy(string); + + string = NULL; + ref->count++; + break; + } + } + + if (string != NULL) + { + /* New Reference Element */ + if ((ref = wbxml_strtbl_element_create(string, stat_buff)) == NULL) + { + wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item); + + if (!stat_buff) + wbxml_list_destroy(*strings, wbxml_buffer_destroy_item); + else + wbxml_list_destroy(*strings, NULL); + + *strings = NULL; + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + ref->count++; + + if (!wbxml_list_append(referenced, (void *) ref)) + { + wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item); + + if (!stat_buff) + wbxml_list_destroy(*strings, wbxml_buffer_destroy_item); + else + wbxml_list_destroy(*strings, NULL); + + *strings = NULL; + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + } + + + wbxml_list_destroy(*strings, NULL); + *strings = NULL; + + + /*********************************************** + * Remove Strings that have only One reference + */ + + if ((result = wbxml_list_create()) == NULL) { + wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + while (wbxml_list_len(referenced) > 0) + { + ref = (WBXMLStringTableElement *) wbxml_list_extract_first(referenced); + if ((ref->count > 1) && (wbxml_buffer_len(ref->string) > WBXML_ENCODER_STRING_TABLE_MIN)) { + /* Add Element to String Table */ + if (!wbxml_strtbl_add_element(encoder, ref, NULL, &added)) { + wbxml_strtbl_element_destroy(ref); + wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item); + wbxml_list_destroy(result, wbxml_strtbl_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + if (!added) { + wbxml_strtbl_element_destroy(ref); + } + } + else { + /* Add Element in resulting 'not added in String Table' list */ + if (!wbxml_list_append(result, (void *) ref)) { + wbxml_strtbl_element_destroy(ref); + wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item); + wbxml_list_destroy(result, wbxml_strtbl_element_destroy_item); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + } + + wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item); + + *one_ref = result; + + return WBXML_OK; +} + + +/** + * @brief Add a String in String table + * @param encoder [in] The WBXML Encoder + * @param elt [in] The Element to add + * @param index [out] The index in String Table + * @param added [out] TRUE if really added, or FALSe if already in String Table + * @return TRUE if no error, FALSE is Memory Error + */ +static WB_BOOL wbxml_strtbl_add_element(WBXMLEncoder *encoder, WBXMLStringTableElement *elt, WB_ULONG *index, WB_BOOL *added) +{ + WBXMLStringTableElement *elt_tmp = NULL; + WB_ULONG i = 0; + + if ((encoder == NULL) || (encoder->strstbl == NULL) || (elt == NULL) || (elt->string == NULL)) + return FALSE; + + *added = FALSE; + + /* Check if this element already exists in String Table */ + for (i = 0; i < wbxml_list_len(encoder->strstbl); i++) + { + if ((elt_tmp = wbxml_list_get(encoder->strstbl, i)) == NULL) + continue; + + if ((wbxml_buffer_len(elt_tmp->string) == wbxml_buffer_len(elt->string)) && + (wbxml_buffer_compare(elt_tmp->string, elt->string) == 0)) + { + /* The String already exists in the String Table */ + if (index != NULL) + *index = elt_tmp->offset; + return TRUE; + } + } + + /* Add this string to String Table */ + elt->offset = encoder->strstbl_len; + + if (!wbxml_list_append(encoder->strstbl, (void *) elt)) + return FALSE; + + /* Index in String Table */ + if (index != NULL) + *index = encoder->strstbl_len; + + /* New String Table length */ + encoder->strstbl_len += wbxml_buffer_len(elt->string) + 1; + + *added = TRUE; + + return TRUE; +} + +#endif /* WBXML_ENCODER_USE_STRTBL */ + + +/***************************************** + * XML Output Functions + */ + +/**************************** + * Build XML Result + */ + +/** + * @brief Build XML Result + * @param encoder [in] The WBXML Encoder + * @param xml [out] Resulting XML document + * @param xml_len [out] XML document length + * @return WBXML_OK if built is OK, an error code otherwise + */ +static WBXMLError xml_build_result(WBXMLEncoder *encoder, WB_UTINY **xml, WB_ULONG *xml_len) +{ + WBXMLBuffer *header = NULL; + WB_ULONG len = 0; + WBXMLError ret = WBXML_OK; + + /* Init */ + *xml_len = 0; + + if (encoder->flow_mode == TRUE) { + /* Header already built */ + header = encoder->output_header; + } + else { + /* Create Header Buffer */ + if ((header = wbxml_buffer_create("", 0, WBXML_ENCODER_XML_HEADER_MALLOC_BLOCK)) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Fill Header Buffer */ + if (encoder->xml_encode_header) { + if ((ret = xml_fill_header(encoder, header)) != WBXML_OK) { + wbxml_buffer_destroy(header); + return ret; + } + } + } + + /* Result Buffer Length */ + len = wbxml_buffer_len(header) + wbxml_buffer_len(encoder->output); + + /* Create Result Buffer */ + *xml = (WB_UTINY *) wbxml_malloc((len + 1) * sizeof(WB_UTINY)); + if (*xml == NULL) { + if (encoder->flow_mode == FALSE) + wbxml_buffer_destroy(header); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /** @todo Use the 'output_charset' field */ + + /* Copy Header to Result */ + memcpy(*xml, wbxml_buffer_get_cstr(header), wbxml_buffer_len(header)); + + /* Copy XML Document to Result */ + memcpy(*xml + wbxml_buffer_len(header), wbxml_buffer_get_cstr(encoder->output), wbxml_buffer_len(encoder->output)); + + /** @todo Remove this NULL char if not needed by charset */ + + /* NULL Terminated Buffer */ + (*xml)[len] = '\0'; + + /* Set length */ + if (xml_len != NULL) + *xml_len = len; + + /* Clean-up */ + if (encoder->flow_mode == FALSE) + wbxml_buffer_destroy(header); + + return WBXML_OK; +} + + +/** + * @brief Fill the XML Header + * @param encoder The WBXML Encoder + * @param header The Buffer to Fill + * @return WBXML_OK if built is OK, an error code otherwise + */ +static WBXMLError xml_fill_header(WBXMLEncoder *encoder, WBXMLBuffer *header) +{ + if ((encoder == NULL) || (header == NULL)) + return WBXML_ERROR_BAD_PARAMETER; + + /** @todo Add 'encoding' info */ + + /* */ + if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_HEADER)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* New Line */ + if (encoder->xml_gen_type == WBXML_GEN_XML_INDENT) { + if (!xml_encode_new_line(header)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + /* lang->publicID->xmlRootElt)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + if (encoder->lang->publicID->xmlPublicID && + WBXML_STRLEN(encoder->lang->publicID->xmlPublicID)) { + + /* PUBLIC " */ + if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_PUBLIC_START)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Public ID */ + if (!wbxml_buffer_append_cstr(header, encoder->lang->publicID->xmlPublicID)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* " */ + if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_PUBLIC_END)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } else { + /* SYSTEM */ + if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_SYSTEM)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + /* DTD */ + if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_DTD)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* DTD */ + if (!wbxml_buffer_append_cstr(header, encoder->lang->publicID->xmlDTD)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* "> */ + if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_END_DTD)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* New Line */ + if (encoder->xml_gen_type == WBXML_GEN_XML_INDENT) { + if (!xml_encode_new_line(header)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + return WBXML_OK; +} + + +/**************************** + * XML Encoding Functions + */ + +/** + * @brief Encode an XML Tag + * @param encoder The WBXML Encoder + * @param node The element to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError xml_encode_tag(WBXMLEncoder *encoder, WBXMLTreeNode *node) +{ + const WB_TINY *ns = NULL; + WB_UTINY i; + + /* Set as current Tag */ + if (node->name->type == WBXML_VALUE_TOKEN) + encoder->current_tag = node->name->u.token; + else + encoder->current_tag = NULL; + + /* Indent */ + if (encoder->xml_gen_type == WBXML_GEN_XML_INDENT) { + for (i=0; i<(encoder->indent * encoder->indent_delta); i++) { + if (!wbxml_buffer_append_char(encoder->output, ' ')) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + } + + /* Append < */ + if (!wbxml_buffer_append_char(encoder->output, '<')) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Append Element Name */ + if (!wbxml_buffer_append_cstr(encoder->output, wbxml_tag_get_xml_name(node->name))) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* NameSpace handling: Check if Current Node Code Page is different than Parent Node Code Page */ + if ((encoder->lang->nsTable != NULL) && + ((node->parent == NULL) || + ((node->parent->type == WBXML_TREE_ELEMENT_NODE) && + (node->parent->name->type == WBXML_VALUE_TOKEN) && + (node->type == WBXML_TREE_ELEMENT_NODE) && + (node->name->type == WBXML_VALUE_TOKEN) && + (node->parent->name->u.token->wbxmlCodePage != node->name->u.token->wbxmlCodePage)))) + { + if ((ns = wbxml_tables_get_xmlns(encoder->lang->nsTable, node->name->u.token->wbxmlCodePage)) != NULL) + { + /* Append xmlns=" */ + if (!wbxml_buffer_append_cstr(encoder->output, " xmlns=\"")) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Append NameSpace */ + if (!wbxml_buffer_append_cstr(encoder->output, ns)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Append " */ + if (!wbxml_buffer_append_char(encoder->output, '"')) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + } + + return WBXML_OK; +} + + +/** + * @brief Encode an XML End Tag + * @param encoder The WBXML Encoder + * @param node Tag + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError xml_encode_end_tag(WBXMLEncoder *encoder, WBXMLTreeNode *node) +{ + WB_UTINY i; + + if (encoder->xml_gen_type == WBXML_GEN_XML_INDENT) { + +#if defined( WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT ) + if (wbxml_tree_node_have_child_elt(node)) { +#endif /* WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT */ + + /* Add a New Line if there were content in this element */ + if (encoder->in_content) { + if (!xml_encode_new_line(encoder->output)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + encoder->indent--; + + /* Indent End Element */ + for (i=0; i<(encoder->indent * encoder->indent_delta); i++) { + if (!wbxml_buffer_append_char(encoder->output, ' ')) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + +#if defined( WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT ) + } +#endif /* WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT */ + + } + + /* Append output, "output, wbxml_tag_get_xml_name(node->name))) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Append > */ + if (!wbxml_buffer_append_char(encoder->output, '>')) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* New Line */ + if (encoder->xml_gen_type == WBXML_GEN_XML_INDENT) { + if (!xml_encode_new_line(encoder->output)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + /* No more in content */ + encoder->in_content = FALSE; + + return WBXML_OK; +} + + +/** + * @brief Encode a XML Attribute + * @param encoder [in] The WBXML Encoder + * @param attribute [in] The Attribute to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError xml_encode_attr(WBXMLEncoder *encoder, WBXMLAttribute *attribute) +{ + /* Append a space */ + if (!wbxml_buffer_append_char(encoder->output, ' ')) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Append Attribute Name */ + if (!wbxml_buffer_append_cstr(encoder->output, wbxml_attribute_get_xml_name(attribute))) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Append =" */ + if (!wbxml_buffer_append_cstr(encoder->output, "=\"")) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + if (wbxml_attribute_get_xml_value(attribute) != NULL) { + /* Fix Attribute Value text */ + WBXMLBuffer *tmp = NULL; + + /* Work with a temporary copy */ + if ((tmp = wbxml_buffer_create_from_cstr(wbxml_attribute_get_xml_value(attribute))) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Fix text */ + if (xml_encode_text_entities(encoder, tmp)) { + wbxml_buffer_destroy(tmp); + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + wbxml_buffer_destroy(tmp); + } + + /* Append " */ + if (!wbxml_buffer_append_char(encoder->output, '"')) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} + + +/** + * @brief Encode a End of XML Attributes List + * @param encoder [in] The WBXML Encoder + * @param node [in] Current node + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError xml_encode_end_attrs(WBXMLEncoder *encoder, WBXMLTreeNode *node) +{ +#if defined( WBXML_ENCODER_XML_GEN_EMPTY_ELT ) + + if (node->children == NULL) { + /* Append " />" */ + if (!wbxml_buffer_append_cstr(encoder->output, "/>")) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* New Line */ + if (encoder->xml_gen_type == WBXML_GEN_XML_INDENT) { + if (!xml_encode_new_line(encoder->output)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + } + else { + +#endif /* WBXML_ENCODER_XML_GEN_EMPTY_ELT */ + + /* Append > */ + if (!wbxml_buffer_append_char(encoder->output, '>')) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* New Line */ + if (encoder->xml_gen_type == WBXML_GEN_XML_INDENT) { + +#if defined( WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT ) + if (wbxml_tree_node_have_child_elt(node)) { +#endif /* WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT */ + + if (!xml_encode_new_line(encoder->output)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + /* Increment indentation */ + encoder->indent++; + +#if defined( WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT ) + } +#endif /* WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT */ + + } + +#if defined( WBXML_ENCODER_XML_GEN_EMPTY_ELT ) + + } + +#endif /* WBXML_ENCODER_XML_GEN_EMPTY_ELT */ + + return WBXML_OK; +} + +/** + * @brief Encode an XML Text + * @param encoder The WBXML Encoder + * @param node The node containing XML Text to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError xml_encode_text(WBXMLEncoder *encoder, WBXMLTreeNode *node) +{ + WBXMLBuffer *str = node->content; + WBXMLBuffer *tmp = NULL; + WB_UTINY i = 0; + + if (encoder->in_cdata) { + /* If we are in a CDATA section, do not modify the text to encode */ + if (!wbxml_buffer_append(encoder->output, str)) + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + else { + /* Work with a temporary copy */ + if ((tmp = wbxml_buffer_duplicate(str)) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Indent */ + if ((encoder->xml_gen_type == WBXML_GEN_XML_INDENT) && + (!encoder->in_content)) + { +#if defined( WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT ) + if (wbxml_tree_node_have_child_elt(node)) { +#endif /* WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT */ + + /* Indent Content (only indent in first call to xml_encode_text()) */ + for (i=0; i<(encoder->indent * encoder->indent_delta); i++) { + if (!wbxml_buffer_append_char(encoder->output, ' ')) { + wbxml_buffer_destroy(tmp); + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + } + +#if defined( WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT ) + } +#endif /* WBXML_ENCODER_XML_NO_EMPTY_ELT_INDENT */ + } + +#if defined( WBXML_SUPPORT_SYNCML ) + /* Change text in from "application/vnd.syncml-devinf+wbxml" to "application/vnd.syncml-devinf+xml" */ + if (((encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML10) || + (encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML11) || + (encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML12)) && + (encoder->current_tag != NULL) && + (encoder->current_tag->wbxmlCodePage == 0x01 ) && + (encoder->current_tag->wbxmlToken == 0x13 ) && + (wbxml_buffer_compare_cstr(tmp, "application/vnd.syncml-devinf+wbxml") == 0)) + { + wbxml_buffer_destroy(tmp); + + /* Change Content */ + if ((tmp = wbxml_buffer_create_from_cstr("application/vnd.syncml-devinf+xml")) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + /* Change text in from "application/vnd.syncml.dmtnds+wbxml" to "application/vnd.syncml.dmtnds+xml" */ + if ((encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML12) && + (encoder->current_tag != NULL) && + (encoder->current_tag->wbxmlCodePage == 0x01 ) && + (encoder->current_tag->wbxmlToken == 0x13 ) && + (wbxml_buffer_compare_cstr(tmp, "application/vnd.syncml.dmtnds+wbxml") == 0)) + { + wbxml_buffer_destroy(tmp); + + /* Change Content */ + if ((tmp = wbxml_buffer_create_from_cstr("application/vnd.syncml.dmtnds+xml")) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } +#endif /* WBXML_SUPPORT_SYNCML */ + + /* Some elements are transferred as WBXML opaque data. They contain + * binary data that isn't necessary valid in XML, so return them in Base + * 64. + */ + if (encoder->current_tag != NULL && + encoder->current_tag->options & WBXML_TAG_OPTION_BINARY) + { + WBXMLError ret; + if ((ret = wbxml_buffer_encode_base64(tmp)) != WBXML_OK) { + wbxml_buffer_destroy(tmp); + return ret; + } + } + + /* Fix text */ + if (xml_encode_text_entities(encoder, tmp)) { + wbxml_buffer_destroy(tmp); + return WBXML_ERROR_ENCODER_APPEND_DATA; + } + + /* Clean-up */ + wbxml_buffer_destroy(tmp); + } + + encoder->in_content = TRUE; + + return WBXML_OK; +} + + +/** + * @brief Append a New Line to a Buffer + * @param buff The Buffer + * @return TRUE if added, FALSE otherwise + */ +static WB_BOOL xml_encode_new_line(WBXMLBuffer *buff) +{ + if (buff == NULL) + return FALSE; + + return wbxml_buffer_append_data(buff, WBXML_ENCODER_XML_NEW_LINE, WBXML_STRLEN(WBXML_ENCODER_XML_NEW_LINE)); +} + + +/** + * @brief Fix an XML text buffer (content text or attribute value) + * @param buff The Buffer to fix + * @param normalize Normalize text ? + * @return WBXML_OK if ok, an Error Code otherwise + * @note Reference: http://www.w3.org/TR/2004/REC-xml-20040204/#syntax + */ +static WBXMLError xml_encode_text_entities(WBXMLEncoder *encoder, WBXMLBuffer *buff) +{ + WB_ULONG i = 0; + WB_UTINY ch; + WB_BOOL normalize = (WB_BOOL) (encoder->xml_gen_type == WBXML_GEN_XML_CANONICAL); + + for (i = 0; i < wbxml_buffer_len(buff); i++) { + if (!wbxml_buffer_get_char(buff, i, &ch)) + continue; + + switch (ch) { + case '<': + /* Write "<" */ + if (!wbxml_buffer_append_cstr(encoder->output, (WB_UTINY *) xml_lt)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + break; + + case '>': + /* Write ">" */ + if (!wbxml_buffer_append_cstr(encoder->output, (WB_UTINY *) xml_gt)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + break; + + case '&': + /* Write "&" */ + if (!wbxml_buffer_append_cstr(encoder->output, (WB_UTINY *) xml_amp)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + break; + + case '"': + /* Write """ */ + if (!wbxml_buffer_append_cstr(encoder->output, (WB_UTINY *) xml_quot)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + break; + + case '\'': + /* Write "'" */ + if (!wbxml_buffer_append_cstr(encoder->output, (WB_UTINY *) xml_apos)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + break; + + case '\r': + if (normalize) { + /* Write " " */ + if (!wbxml_buffer_append_cstr(encoder->output, (WB_UTINY *) xml_slashr)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + break; + } + + case '\n': + if (normalize) { + /* Write " " */ + if (!wbxml_buffer_append_cstr(encoder->output, (WB_UTINY *) xml_slashn)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + break; + } + + case '\t': + if (normalize) { + /* Write " " */ + if (!wbxml_buffer_append_cstr(encoder->output, (WB_UTINY *) xml_tab)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + break; + } + + default: + if (!wbxml_buffer_append_char(encoder->output, ch)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + break; + } + } + + return WBXML_OK; +} + + +/** + * @brief Encode a begin of CDATA section + * @param encoder The WBXML Encoder + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError xml_encode_cdata(WBXMLEncoder *encoder) +{ + /* Append output, " */ + if (!wbxml_buffer_append_cstr(encoder->output, "]]>")) + return WBXML_ERROR_ENCODER_APPEND_DATA; + + return WBXML_OK; +} + + +/** + * @brief Encode an encapsulated WBXML Tree to XML + * @param encoder [in] The WBXML Encoder + * @param tree [in] The WBXML Tree to encode + * @return WBXML_OK if encoding is OK, an error code otherwise + */ +static WBXMLError xml_encode_tree(WBXMLEncoder *encoder, WBXMLTree *tree) +{ + WBXMLEncoder *new_encoder = NULL; + WB_UTINY *xml = NULL; + WB_ULONG xml_len = 0; + WBXMLError ret = WBXML_OK; + + if ((new_encoder = encoder_duplicate(encoder)) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Set Tree */ + new_encoder->tree = tree; + + /* Encode to XML */ + if ((ret = wbxml_encoder_encode_tree_to_xml(new_encoder, &xml, &xml_len)) != WBXML_OK) { + wbxml_encoder_destroy(new_encoder); + return ret; + } + + /* Clean-up */ + wbxml_encoder_destroy(new_encoder); + + /** @bug Handle output_charset ! */ + + /* Append xml to output */ + if (!wbxml_buffer_append_cstr(encoder->output, xml)) { + wbxml_free(xml); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Clean-up */ + wbxml_free(xml); + + return WBXML_OK; +} diff --git a/src/wbxml_encoder.h b/src/wbxml_encoder.h new file mode 100644 index 0000000..d879e13 --- /dev/null +++ b/src/wbxml_encoder.h @@ -0,0 +1,319 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_encoder.h + * @ingroup wbxml_encoder + * + * @author Aymerick Jehanne + * @date 11/11/02 + * + * @brief WBXML Encoder - Encodes a WBXML Tree to WBXML or to XML + */ + +#ifndef WBXML_ENCODER_H +#define WBXML_ENCODER_H + +#include "wbxml.h" +#include "wbxml_tree.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_encoder + * @{ + */ + +/** + * @brief WBXML Encoder + */ +typedef struct WBXMLEncoder_s WBXMLEncoder; + +/** + * @brief WBXML Encoder Output Type + */ +typedef enum WBXMLEncoderOutputType_e { + WBXML_ENCODER_OUTPUT_WBXML = 0, + WBXML_ENCODER_OUTPUT_XML +} WBXMLEncoderOutputType; + + +/** + * @brief Create a WBXML Encoder + * @result Return the newly created WBXMLEncoder, or NULL if not enough memory + * @warning Do NOT use this function directly, use wbxml_encoder_create() macro instead + */ +WBXML_DECLARE(WBXMLEncoder *) wbxml_encoder_create_real(void); +#define wbxml_encoder_create() wbxml_mem_cleam(wbxml_encoder_create_real()) + +/** + * @brief Destroy a WBXML Encoder + * @param encoder The WBXMLEncoder to free + */ +WBXML_DECLARE(void) wbxml_encoder_destroy(WBXMLEncoder *encoder); + +/** + * @brief Reset a WBXML Encoder + * @param encoder The WBXMLEncoder to reset + */ +WBXML_DECLARE(void) wbxml_encoder_reset(WBXMLEncoder *encoder); + + +/** + * @brief Set the WBXML Encoder to ignore empty texts (ie: ignorable Whitespaces) [Default: FALSE] + * @param encoder [in] The WBXML Encoder + * @param set_ignore [in] TRUE if ignore, FALSE otherwise + * @warning This behaviour can me overriden by the WBXML_GEN_XML_CANONICAL mode (set by wbxml_encoder_set_xml_gen_type()) + */ +WBXML_DECLARE(void) wbxml_encoder_set_ignore_empty_text(WBXMLEncoder *encoder, WB_BOOL set_ignore); + +/** + * @brief Set the WBXML Encoder to remove leading and trailing blanks in texts [Default: FALSE] + * @param encoder [in] The WBXML Encoder + * @param set_remove [in] TRUE if remove, FALSE otherwise + * @warning This behaviour can me overriden by the WBXML_GEN_XML_CANONICAL mode (set by wbxml_encoder_set_xml_gen_type()) + */ +WBXML_DECLARE(void) wbxml_encoder_set_remove_text_blanks(WBXMLEncoder *encoder, WB_BOOL set_remove); + +/** + * @brief Set output document Charset Encoding + * @param encoder [in] The WBXML Encoder + * @param charset [in] The Charset to set + * @note - This overrides the Charset Encoding found in WBXML Tree. + * - If not set with this function, the 'orig_charset' field of the WBXML Tree is used + * (ie the Charset Encoding of the original document). + * - If no 'orig_charset' is set in WBXML Tree, the default charset is used : + * - 'WBXML_ENCODER_WBXML_DEFAULT_CHARSET' when encoding to XML + * - 'WBXML_ENCODER_XML_DEFAULT_CHARSET' when encoding to WBXML + */ +WBXML_DECLARE(void) wbxml_encoder_set_output_charset(WBXMLEncoder *encoder, WBXMLCharsetMIBEnum charset); + + +/** + * @brief Set if we use String Table when Encoding into WBXML [Default: TRUE] + * @param encoder [in] The WBXML Encoder + * @param use_strtbl [in] TRUE if we use String Table, FALSE otherwise + * @note This function has no effect if WBXML_ENCODER_USE_STRTBL compilation flag is not set + */ +WBXML_DECLARE(void) wbxml_encoder_set_use_strtbl(WBXMLEncoder *encoder, WB_BOOL use_strtbl); + +/** + * @brief Set if we want to produce anonymous WBXML documents [Default: FALSE] + * @param encoder [in] The WBXML encoder + * @param set_anonymous [in] TRUE to produce anonymous documents, FALSE otherwise + */ +WBXML_DECLARE(void) wbxml_encoder_set_produce_anonymous(WBXMLEncoder *encoder, WB_BOOL set_anonymous); + +/** + * @brief Set the WBXML Version of the output document, when generating WBXML [Default: 'WBXML_VERSION_TOKEN_13' (1.3)] + * @param encoder [in] The WBXML Encoder + * @param version [in] The WBXML Version + */ +WBXML_DECLARE(void) wbxml_encoder_set_wbxml_version(WBXMLEncoder *encoder, WBXMLVersion version); + + +/** + * @brief Set the WBXML Encoder XML Generation Type, when generating XML [Default: WBXML_GEN_XML_COMPACT] + * @param encoder [in] The WBXML Encoder + * @param gen_type [in] Generation Type (cf. WBXMLEncoderXMLGen enum) + */ +WBXML_DECLARE(void) wbxml_encoder_set_xml_gen_type(WBXMLEncoder *encoder, WBXMLGenXMLType gen_type); + +/** + * @brief Set the WBXML Encoder indent, when generating XML in WBXML_GEN_XML_INDENT mode [Default: 0] + * @param encoder [in] The WBXML Encoder + * @param indent [in] If 'WBXML_GEN_XML_INDENT' type is used, this is the number of spaces for indent + */ +WBXML_DECLARE(void) wbxml_encoder_set_indent(WBXMLEncoder *encoder, WB_UTINY indent); + + +/** + * @brief Set the WBXML Tree to encode + * + * Use this method before calling wbxml_encoder_encode_tree_to_wbxml() or wbxml_encoder_encode_tree_to_xml(). + * + * @param encoder [in] The WBXML Encoder to use + * @param tree [in] The WBXML Tree to encode + */ +WBXML_DECLARE(void) wbxml_encoder_set_tree(WBXMLEncoder *encoder, WBXMLTree *tree); + +/** + * @brief Encode the WBXML Tree attached to this encoder into WBXML + * + * Call wbxml_encoder_set_tree() before using this method. + * + * @param encoder [in] The WBXML Encoder to use + * @param wbxml [out] Resulting WBXML document + * @param wbxml_len [out] The resulting WBXML document length + * @return Return WBXML_OK if no error, an error code otherwise + * @warning The 'encoder->tree' WBXMLLib Tree MUST be already set with a call to wbxml_encoder_set_tree() function + */ +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_tree_to_wbxml(WBXMLEncoder *encoder, WB_UTINY **wbxml, WB_ULONG *wbxml_len); + +/* BC */ +#define wbxml_encoder_encode_to_wbxml(a,b,c) wbxml_encoder_encode_tree_to_wbxml(a,b,c) + +/** + * @brief Encode the WBXML Tree attached to this encoder into XML + * + * Call wbxml_encoder_set_tree() before using this method. + * + * @param encoder [in] The WBXML Encoder to use + * @param xml [out] Resulting XML document + * @param xml_len [out] XML document length + * @return Return WBXML_OK if no error, an error code otherwise + * @warning The 'encoder->tree' WBXMLLib Tree MUST be already set with a call to wbxml_encoder_set_tree() function + */ +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_tree_to_xml(WBXMLEncoder *encoder, WB_UTINY **xml, WB_ULONG *xml_len); + +/* BC */ +#define wbxml_encoder_encode_to_xml(a,b,c) wbxml_encoder_encode_tree_to_xml(a,b,c) + + +/** + * @brief Set the encoder into 'Flow Mode' (to encode nodes directly) + * + * Use this method to the set the encoder in 'Flow Mode'. This permits to encode WBXML Nodes 'on the fly', without + * having to encode a whole WBXML Tree. + * + * You should use this function (with TRUE parameter) before calling wbxml_encoder_encode_node(). + * + * @param encoder [in] The WBXML Encoder to use + * @param flow_mode [in] Set Flow Mode ? + * @return Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_encoder_set_flow_mode(WBXMLEncoder *encoder, WB_BOOL flow_mode); + +/** + * @brief Set the output type (WBXML_ENCODER_OUTPUT_XML | WBXML_ENCODER_OUTPUT_WBXML) + * @param encoder [in] The WBXML Encoder + * @param output_type [in] The output type + */ +WBXML_DECLARE(void) wbxml_encoder_set_output_type(WBXMLEncoder *encoder, WBXMLEncoderOutputType output_type); + +/** + * @brief Set the language to use + * @param encoder [in] The WBXML Encoder + * @param lang [in] The language to use + */ +WBXML_DECLARE(void) wbxml_encoder_set_lang(WBXMLEncoder *encoder, WBXMLLanguage lang); + +/** + * @brief Generate textual Public ID instead of token + * @param encoder [in] The WBXML Encoder + * @param gen_text [in] Set or unset + */ +WBXML_DECLARE(void) wbxml_encoder_set_text_public_id(WBXMLEncoder *encoder, WB_BOOL gen_text); + +/** + * @brief Encode a WBXML Tree Node + * + * This function directly encode a WBXMLTreeNode. So you can use if you don't want to encode a whole WBXML Tree. + * + * You should call wbxml_encoder_set_flow_mode(TRUE), wbxml_encoder_set_output_type() before using this function. + * You must call wbxml_encoder_set_lang() before using this function. + * + * @param encoder [in] The WBXML Encoder to use + * @param node [in] The WBXML Tree Node to encode + * @return Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_node(WBXMLEncoder *encoder, WBXMLTreeNode *node); + +/** + * @brief Encode node, but if node is an Element, choose the encode 'end' tag or not + * + * @param encoder [in] The WBXML Encoder to use + * @param node [in] The WBXML Tree Node to encode + * @param enc_end [in] Encoded element 'end' ? + * @return Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_node_with_elt_end(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL enc_end); + +/** + * @brief Encode a WBXML Tree + * + * You should call wbxml_encoder_set_flow_mode(TRUE), wbxml_encoder_set_output_type() before using this function. + * + * @param encoder [in] The WBXML Encoder to use + * @param tree [in] The WBXML Tree to encode + * @return Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_tree(WBXMLEncoder *encoder, WBXMLTree *tree); + +/** + * @brief Encode a raw element start + * @param encoder [in] The WBXML Encoder to use + * @param node [in] The WBXML Tree Node representing the element start to encode + * @param has_content [in] Does the element has content ? + * @return Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_raw_elt_start(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content); + +/** + * @brief Encode a raw element end + * @param encoder [in] The WBXML Encoder to use + * @param node [in] The WBXML Tree Node representing the element end to encode + * @param has_content [in] Does the element has content ? + * @return Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_raw_elt_end(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content); + +/** + * @brief Get currently encoded buffer + * @param encoder [in] The WBXML Encoder to use + * @param result [out] Resulting buffer + * @param result_len [out] Resulting buffer length + * @return Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_encoder_get_output(WBXMLEncoder *encoder, WB_UTINY **result, WB_ULONG *result_len); + +/** + * @brief Get currently encoded buffer length + * @param encoder [in] The WBXML Encoder to use + * @return Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WB_ULONG) wbxml_encoder_get_output_len(WBXMLEncoder *encoder); + +/** + * @brief Delete bytes from output buffer (from end of buffer) + * @param encoder [in] The WBXML Encoder to use + * @param nb [in] Number of bytes to delete + */ +WBXML_DECLARE(void) wbxml_encoder_delete_output_bytes(WBXMLEncoder *encoder, WB_ULONG nb); + +/** + * @brief Delete last encoded node + * @param encoder [in] The WBXML Encoder to use + */ +WBXML_DECLARE(void) wbxml_encoder_delete_last_node(WBXMLEncoder *encoder); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_ENCODER_H */ diff --git a/src/wbxml_errors.c b/src/wbxml_errors.c new file mode 100644 index 0000000..bfecd31 --- /dev/null +++ b/src/wbxml_errors.c @@ -0,0 +1,136 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_errors.c + * @ingroup wbxml_errors + * + * @author Aymerick Jehanne + * @date 02/11/18 + * + * @brief WBXML Error Codes Handling + */ + +#include "wbxml_errors.h" +#include + + +/** + * @brief Error Code item + */ +typedef struct WBXMLErrorCodeItem_s { + WBXMLError code; /**< Error Code */ + const WB_TINY *string; /**< Error Description */ +} WBXMLErrorCodeItem; + + +/** + * @brief Error Code table + */ +static const WBXMLErrorCodeItem error_table [] = { + /* Generic Errors */ + { WBXML_OK, "No Error" }, + { WBXML_NOT_ENCODED, "Not Encoded" }, + { WBXML_ERROR_ATTR_TABLE_UNDEFINED, "Attribute Table Undefined" }, + { WBXML_ERROR_BAD_DATETIME, "Bad %Datetime Format" }, + { WBXML_ERROR_BAD_PARAMETER, "Bad Parameter" }, + { WBXML_ERROR_INTERNAL, "Internal Error" }, + { WBXML_ERROR_LANG_TABLE_UNDEFINED, "Languages Table Undefined" }, + { WBXML_ERROR_NOT_ENOUGH_MEMORY, "Not Enough Memory" }, + { WBXML_ERROR_NOT_IMPLEMENTED, "Not Implemented" }, + { WBXML_ERROR_TAG_TABLE_UNDEFINED, "Tag Table Undefined" }, + { WBXML_ERROR_B64_ENC, "Failed to encode Base64" }, + { WBXML_ERROR_B64_DEC, "Failed to decode Base64" }, +#if defined( WBXML_SUPPORT_WV ) + { WBXML_ERROR_WV_DATETIME_FORMAT, "Bad Wireless-Village Date and Time Format" }, +#endif /* WBXML_SUPPORT_WV */ + { WBXML_ERROR_NO_CHARSET_CONV, "No built-in charset convertor (Compiled without libiconv)" }, + { WBXML_ERROR_CHARSET_STR_LEN, "Bad string length, can't convert" }, + /* WBXML Parser Errors */ + { WBXML_ERROR_ATTR_VALUE_TABLE_UNDEFINED, "Attribute Value Table Undefined" }, + { WBXML_ERROR_BAD_LITERAL_INDEX, "Bad Literal Index" }, + { WBXML_ERROR_BAD_NULL_TERMINATED_STRING_IN_STRING_TABLE, "Not NULL Terminated String in String Table" }, + { WBXML_ERROR_BAD_OPAQUE_LENGTH, "Bad Opaque Length" }, + { WBXML_ERROR_EMPTY_WBXML, "Empty WBXML" }, + { WBXML_ERROR_END_OF_BUFFER, "Unexpected End Of WBXML Buffer" }, + { WBXML_ERROR_ENTITY_CODE_OVERFLOW, "Entity Code Overflow" }, + { WBXML_ERROR_EXT_VALUE_TABLE_UNDEFINED, "Extension Value Table Undefined" }, + { WBXML_ERROR_INVALID_STRTBL_INDEX, "Invalid String Table Index" }, + { WBXML_ERROR_LITERAL_NOT_NULL_TERMINATED_IN_STRING_TABLE, "Literal Not NULL Terminated in String Table" }, + { WBXML_ERROR_NOT_NULL_TERMINATED_INLINE_STRING, "Not NULL Terminated Inline String" }, + { WBXML_ERROR_NULL_PARSER, "Null Parser" }, + { WBXML_ERROR_NULL_STRING_TABLE, "No String Table In Document" }, + { WBXML_ERROR_STRING_EXPECTED, "String Expected" }, + { WBXML_ERROR_STRTBL_LENGTH, "Bad String Table Length" }, + { WBXML_ERROR_UNKNOWN_ATTR, "Unknown Attribute" }, + { WBXML_ERROR_UNKNOWN_ATTR_VALUE, "Unknown Attribute Value" }, + { WBXML_ERROR_UNKNOWN_EXTENSION_TOKEN, "Unknown Extension Token" }, + { WBXML_ERROR_UNKNOWN_EXTENSION_VALUE, "Unknown Extension Value token" }, + { WBXML_ERROR_UNKNOWN_PUBLIC_ID, "Unknown Public ID" }, + { WBXML_ERROR_UNKNOWN_TAG, "Unknown Tag" }, + { WBXML_ERROR_UNVALID_MBUINT32, "Unvalid MultiByte UINT32" }, +#if defined( WBXML_SUPPORT_WV ) + { WBXML_ERROR_WV_INTEGER_OVERFLOW, "Wireless-Village Integer Overflow" }, +#endif /* WBXML_SUPPORT_WV */ + /* WBXML Encoder Errors */ + { WBXML_ERROR_ENCODER_APPEND_DATA, "Can't append data to output buffer" }, + { WBXML_ERROR_STRTBL_DISABLED, "String Table generation disabled: can't encode Literal" }, + { WBXML_ERROR_UNKNOWN_XML_LANGUAGE, "The XML language is unknown." }, + { WBXML_ERROR_XML_NODE_NOT_ALLOWED, "XML Node Type not allowed" }, + { WBXML_ERROR_XML_NULL_ATTR_NAME, "NULL XML Attribute Name" }, + { WBXML_ERROR_XML_PARSING_FAILED, "Parsing of XML Document Failed" }, +#if defined( WBXML_SUPPORT_SYNCML ) + { WBXML_ERROR_XML_DEVINF_CONV_FAILED, "The conversion of a XML DevInf document failed" }, +#endif /* WBXML_SUPPORT_WV */ + { WBXML_ERROR_NO_XMLPARSER, "Can't parse XML (Compiled without Expat): XML to WBXML conversion not possible" }, + { WBXML_ERROR_XMLPARSER_OUTPUT_UTF16, "XML Parser (Expat) is outputting UTF-16, so you have two choices :\n" + " - Get the iconv library (http://www.gnu.org/software/libiconv/)\n" + " - Use a version of Expat that output UTF-8" }, + { WBXML_ERROR_CHARSET_UNKNOWN, "The character set is unknown."}, + { WBXML_ERROR_CHARSET_CONV_INIT, "The converter for the character set cannot be initialized."}, + { WBXML_ERROR_CHARSET_CONV, "The character conversion failed."}, + { WBXML_ERROR_CHARSET_NOT_FOUND, "The character set cannot be found."} +}; + +#define ERROR_TABLE_SIZE ((WB_ULONG) (sizeof(error_table) / sizeof(error_table[0]))) + + +/*************************************************** + * Public Functions + */ + +WBXML_DECLARE(const WB_UTINY *) wbxml_errors_string(WBXMLError error_code) +{ + WB_ULONG i; + + for (i=0; i < ERROR_TABLE_SIZE; i++) { + if (error_table[i].code == error_code) + return (const WB_UTINY *)error_table[i].string; + } + + fprintf(stderr, "PACKAGE_NAME: Unknown error code %d.\n", error_code); + + return (const WB_UTINY *)"Unknown Error Code"; +} diff --git a/src/wbxml_errors.h b/src/wbxml_errors.h new file mode 100644 index 0000000..b8421be --- /dev/null +++ b/src/wbxml_errors.h @@ -0,0 +1,130 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_errors.h + * @ingroup wbxml_errors + * + * @author Aymerick Jehanne + * @date 02/11/18 + * + * @brief WBXML Error Codes Handling + */ + +#ifndef WBXML_ERRORS_H +#define WBXML_ERRORS_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "wbxml_config.h" +#include "wbxml_defines.h" + +/** @addtogroup wbxml_errors + * @{ + */ + +/** + * @brief The WBXML Parser Errors enumeration + */ +typedef enum WBXMLError_e { + /* Generic Errors */ + WBXML_OK = 0, /**< No Error */ + WBXML_NOT_ENCODED = 1, /**< Not an error; just a special internal return code */ + WBXML_ERROR_ATTR_TABLE_UNDEFINED = 10, + WBXML_ERROR_BAD_DATETIME = 11, + WBXML_ERROR_BAD_PARAMETER = 12, + WBXML_ERROR_INTERNAL = 13, + WBXML_ERROR_LANG_TABLE_UNDEFINED = 14, + WBXML_ERROR_NOT_ENOUGH_MEMORY = 15, + WBXML_ERROR_NOT_IMPLEMENTED = 16, + WBXML_ERROR_TAG_TABLE_UNDEFINED = 17, + WBXML_ERROR_B64_ENC = 18, + WBXML_ERROR_B64_DEC = 19, +#if defined( WBXML_SUPPORT_WV ) + WBXML_ERROR_WV_DATETIME_FORMAT = 20, +#endif /* WBXML_SUPPORT_WV */ + WBXML_ERROR_NO_CHARSET_CONV = 30, + WBXML_ERROR_CHARSET_STR_LEN = 31, + WBXML_ERROR_CHARSET_UNKNOWN = 32, + WBXML_ERROR_CHARSET_CONV_INIT = 33, + WBXML_ERROR_CHARSET_CONV = 34, + WBXML_ERROR_CHARSET_NOT_FOUND = 35, + /* WBXML Parser Errors */ + WBXML_ERROR_ATTR_VALUE_TABLE_UNDEFINED = 40, + WBXML_ERROR_BAD_LITERAL_INDEX = 41, + WBXML_ERROR_BAD_NULL_TERMINATED_STRING_IN_STRING_TABLE = 42, + WBXML_ERROR_BAD_OPAQUE_LENGTH = 43, + WBXML_ERROR_EMPTY_WBXML = 44, + WBXML_ERROR_END_OF_BUFFER = 45, + WBXML_ERROR_ENTITY_CODE_OVERFLOW = 46, + WBXML_ERROR_EXT_VALUE_TABLE_UNDEFINED = 47, + WBXML_ERROR_INVALID_STRTBL_INDEX = 48, + WBXML_ERROR_LITERAL_NOT_NULL_TERMINATED_IN_STRING_TABLE = 49, + WBXML_ERROR_NOT_NULL_TERMINATED_INLINE_STRING = 50, + WBXML_ERROR_NULL_PARSER = 51, + WBXML_ERROR_NULL_STRING_TABLE = 52, + WBXML_ERROR_STRING_EXPECTED = 53, + WBXML_ERROR_STRTBL_LENGTH = 54, + WBXML_ERROR_UNKNOWN_ATTR = 60, + WBXML_ERROR_UNKNOWN_ATTR_VALUE = 61, + WBXML_ERROR_UNKNOWN_EXTENSION_TOKEN = 62, + WBXML_ERROR_UNKNOWN_EXTENSION_VALUE = 63, + WBXML_ERROR_UNKNOWN_PUBLIC_ID = 64, + WBXML_ERROR_UNKNOWN_TAG = 65, + WBXML_ERROR_UNVALID_MBUINT32 = 70, +#if defined( WBXML_SUPPORT_WV ) + WBXML_ERROR_WV_INTEGER_OVERFLOW = 80, +#endif /* WBXML_SUPPORT_WV */ + /* WBXML Encoder Errors */ + WBXML_ERROR_ENCODER_APPEND_DATA = 90, + WBXML_ERROR_STRTBL_DISABLED = 100, + WBXML_ERROR_UNKNOWN_XML_LANGUAGE = 101, + WBXML_ERROR_XML_NODE_NOT_ALLOWED = 102, + WBXML_ERROR_XML_NULL_ATTR_NAME = 103, + WBXML_ERROR_XML_PARSING_FAILED = 104, +#if defined( WBXML_SUPPORT_SYNCML ) + WBXML_ERROR_XML_DEVINF_CONV_FAILED = 110, +#endif /* WBXML_SUPPORT_WV */ + WBXML_ERROR_NO_XMLPARSER = 120, + WBXML_ERROR_XMLPARSER_OUTPUT_UTF16 = 121, +} WBXMLError; + + +/** + * @brief Return a String describing an Error Code + * @param error_code WBXML error code + * @return The error description + */ +WBXML_DECLARE(const WB_UTINY *) wbxml_errors_string(WBXMLError error_code); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_ERRORS_H */ diff --git a/src/wbxml_handlers.h b/src/wbxml_handlers.h new file mode 100644 index 0000000..af3dd7c --- /dev/null +++ b/src/wbxml_handlers.h @@ -0,0 +1,118 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_handlers.h + * @ingroup wbxml_parser + * + * @author Aymerick Jehanne + * @date 02/06/09 + * + * @brief WBXML Parser Handlers + */ + +#ifndef WBXML_HANDLERS_H +#define WBXML_HANDLERS_H + +#include "wbxml.h" +#include "wbxml_tables.h" +#include "wbxml_elt.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_parser + * @{ + */ + +/** + * @brief Start Document Handler + * @param ctx User data + * @param charset Charset (The MIBenum from IANA character-sets assignements. See "http://www.iana.org/assignments/character-sets") + * @param lang Language Table for this Document (cf: wbxml_table.[h|c]) + */ +typedef void (*WBXMLStartDocumentHandler)(void *ctx, WBXMLCharsetMIBEnum charset, const WBXMLLangEntry *lang); + +/** + * @brief End Document handler + * @param ctx User data + */ +typedef void (*WBXMLEndDocumentHandler)(void *ctx); + +/** + * @brief Start Element handler + * @param ctx User data + * @param localName The local tag name + * @param atts The attributes attached to the element + * @param empty Set to TRUE if this is an empty element + */ +typedef void (*WBXMLStartElementHandler)(void *ctx, WBXMLTag *localName, WBXMLAttribute **atts, WB_BOOL empty); + +/** + * @brief End Element handler + * @param ctx User data + * @param localName The local tag name + * @param empty Set to TRUE if this is an empty element + */ +typedef void (*WBXMLEndElementHandler)(void *ctx, WBXMLTag *localName, WB_BOOL empty); + +/** + * @brief Characters handler + * @param ctx User data + * @param ch The characters + * @param start The start position in the array + * @param length The number of characters to read from the array + */ +typedef void (*WBXMLCharactersHandler)(void *ctx, WB_UTINY *ch, WB_ULONG start, WB_ULONG length); + +/** + * @brief Processing Instruction Handler + * @param ctx User data + * @param target The processing instruction target. + * @param data The processing instruction data, or null if none was supplied. The data does + * not include any whitespace separating it from the target + */ +typedef void (*WBXMLProcessingInstructionHandler)(void *ctx, const WB_UTINY *target, WB_UTINY *data); + +/** + * @brief WBXMLContentHandler structure + */ +typedef struct WBXMLContentHandler_s { + WBXMLStartDocumentHandler start_document_clb; /**< Start Document Handler */ + WBXMLEndDocumentHandler end_document_clb; /**< End Document handler */ + WBXMLStartElementHandler start_element_clb; /**< Start Element handler */ + WBXMLEndElementHandler end_element_clb; /**< End Element handler */ + WBXMLCharactersHandler characters_clb; /**< Characters handler */ + WBXMLProcessingInstructionHandler pi_clb; /**< Processing Instruction Handler */ +} WBXMLContentHandler; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_HANDLERS_H */ diff --git a/src/wbxml_internals.h b/src/wbxml_internals.h new file mode 100644 index 0000000..90f306f --- /dev/null +++ b/src/wbxml_internals.h @@ -0,0 +1,163 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml.h + * @ingroup wbxml + * + * @author Aymerick Jehanne + * @date 02/11/11 + * + * @brief WBXML Library Main Header + */ + +#ifndef WBXML_INTERNALS_H +#define WBXML_INTERNALS_H + +#include "wbxml.h" + +/** @addtogroup wbxml + * @{ + */ + +/* WBXML Global Tokens */ +#define WBXML_SWITCH_PAGE 0x00 +#define WBXML_END 0x01 +#define WBXML_ENTITY 0x02 +#define WBXML_STR_I 0x03 +#define WBXML_LITERAL 0x04 +#define WBXML_EXT_I_0 0x40 +#define WBXML_EXT_I_1 0x41 +#define WBXML_EXT_I_2 0x42 +#define WBXML_PI 0x43 +#define WBXML_LITERAL_C 0x44 +#define WBXML_EXT_T_0 0x80 +#define WBXML_EXT_T_1 0x81 +#define WBXML_EXT_T_2 0x82 +#define WBXML_STR_T 0x83 +#define WBXML_LITERAL_A 0x84 +#define WBXML_EXT_0 0xC0 +#define WBXML_EXT_1 0xC1 +#define WBXML_EXT_2 0xC2 +#define WBXML_OPAQUE 0xC3 +#define WBXML_LITERAL_AC 0xC4 + +/* WBXML Tokens Masks */ +#define WBXML_TOKEN_MASK 0x3F +#define WBXML_TOKEN_WITH_ATTRS 0x80 +#define WBXML_TOKEN_WITH_CONTENT 0x40 + +/* WBXML Versions (XML text) */ +#define WBXML_VERSION_TEXT_10 "1.0" /**< WBXML 1.0 */ +#define WBXML_VERSION_TEXT_11 "1.1" /**< WBXML 1.1 */ +#define WBXML_VERSION_TEXT_12 "1.2" /**< WBXML 1.2 */ +#define WBXML_VERSION_TEXT_13 "1.3" /**< WBXML 1.3 */ + + +#if defined( WBXML_SUPPORT_WV ) +/** Wireless-Village Specific Data Types */ +typedef enum WBXMLWVDataType_e { + WBXML_WV_DATA_TYPE_BOOLEAN = 0, /**< Boolean */ + WBXML_WV_DATA_TYPE_INTEGER, /**< Integer */ + WBXML_WV_DATA_TYPE_DATE_AND_TIME, /**< Date and Time */ + WBXML_WV_DATA_TYPE_STRING, /**< String */ + WBXML_WV_DATA_TYPE_BINARY /**< Binary */ +} WBXMLWVDataType; +#endif /* WBXML_SUPPORT_WV */ + +/** Generic macro to get number of elements in a table */ +#define WBXML_TABLE_SIZE(table) ((WB_LONG)(sizeof(table) / sizeof(table[0]))) + +/* We are good coders and we don't want to ignore Warnings :) */ +#ifdef WIN32 +#pragma warning(error: 4001) /**< nonstandard extension 'single line comment' was used (disallow "//" C++ comments) */ +#pragma warning(error: 4002) /**< too many actual parameters for macro 'identifier' */ +#pragma warning(error: 4003) /**< not enough actual parameters for macro 'identifier' */ +#pragma warning(error: 4004) /**< incorrect construction after 'defined' */ +#pragma warning(error: 4005) /**< 'identifier' : macro redefinition */ +#pragma warning(error: 4006) /**< #undef expected an identifier */ +#pragma warning(error: 4009) /**< string too big; trailing characters truncated */ +#pragma warning(error: 4013) /**< 'function' undefined; assuming extern returning int */ +#pragma warning(error: 4015) /**< 'identifier' : type of bit field must be integral */ +#pragma warning(error: 4016) /**< 'function' : no function return type; using int as default */ +#pragma warning(error: 4018) /**< 'expression' : signed/unsigned mismatch */ +#pragma warning(error: 4020) /**< 'function' : too many actual parameters */ +#pragma warning(error: 4021) /**< 'function' : too few actual parameters */ +#pragma warning(error: 4022) /**< 'function' : pointer mismatch for actual parameter 'number' */ +#pragma warning(error: 4023) /**< 'symbol' : based pointer passed to unprototyped function : parameter number */ +#pragma warning(error: 4024) /**< 'function' : different types for formal and actual parameter 'number' */ +#pragma warning(error: 4025) /**< 'number' : based pointer passed to function with variable arguments: parameter number */ +#pragma warning(error: 4026) /**< function declared with formal parameter list */ +#pragma warning(error: 4027) /**< function declared without formal parameter list */ +#pragma warning(error: 4028) /**< formal parameter 'number' different from declaration */ +#pragma warning(error: 4029) /**< declared formal parameter list different from definition */ +#pragma warning(error: 4030) /**< first formal parameter list longer than the second list */ +#pragma warning(error: 4031) /**< second formal parameter list longer than the first list */ +#pragma warning(error: 4033) /**< 'function' must return a value */ +#pragma warning(error: 4035) /**< 'function' : no return value */ +#pragma warning(error: 4036) /**< unnamed 'type' as actual parameter */ +#pragma warning(error: 4045) /**< 'identifier' : array bounds overflow */ +#pragma warning(error: 4047) /**< 'identifier1' : 'operator' : different levels of indirection from 'identifier2' */ +#pragma warning(error: 4049) /**< compiler limit : terminating line number emission */ +#pragma warning(error: 4051) /**< type conversion; possible loss of data */ +#pragma warning(error: 4053) /**< one void operand for '?:' */ +#pragma warning(error: 4054) /**< 'conversion' : from function pointer 'type1' to data pointer 'type2' */ +#pragma warning(error: 4057) /**< 'operator' : 'identifier1' indirection to slightly different base types from 'identifier2' */ +#pragma warning(error: 4059) /**< pascal string too big, length byte is length % 256 */ +#pragma warning(error: 4061) /**< enumerate 'identifier' in switch of enum 'identifier' is not explicitly handled by a case label */ +#pragma warning(error: 4063) /**< case 'identifier' is not a valid value for switch of enum 'identifier' */ +#pragma warning(error: 4064) /**< switch of incomplete enum 'identifier' */ +#pragma warning(error: 4071) /**< 'function' : no function prototype given */ +#pragma warning(error: 4072) /**< 'function' : no function prototype on 'convention' function */ +#pragma warning(error: 4078) /**< case constant 'value' too big for the type of the switch expression */ +#pragma warning(error: 4081) /**< expected 'token1'; found 'token2' */ +#pragma warning(error: 4087) /**< 'function' : declared with 'void' parameter list */ +#pragma warning(error: 4088) /**< 'function' : pointer mismatch in actual parameter 'number', formal parameter 'number' */ +#pragma warning(error: 4089) /**< 'function' : different types in actual parameter 'number', formal parameter 'number' */ +#pragma warning(error: 4098) /**< 'function' : void function returning a value */ +#pragma warning(error: 4113) /**< 'identifier1' differs in parameter lists from 'identifier2' */ +#pragma warning(error: 4129) /**< 'character' : unrecognized character escape sequence */ +#pragma warning(error: 4133) /**< 'type' : incompatible types - from 'type1' to 'type2' */ +#pragma warning(error: 4150) /**< deletion of pointer to incomplete type 'type'; no destructor called */ +#pragma warning(error: 4172) /**< returning address of local variable or temporary */ +#pragma warning(error: 4221) /**< nonstandard extension used : 'identifier' : cannot be initialized using address of automatic variable */ +#pragma warning(error: 4223) /**< nonstandard extension used : non-lvalue array converted to pointer */ +#pragma warning(error: 4224) /**< nonstandard extension used : formal parameter 'identifier' was previously defined as a type */ +#pragma warning(error: 4390) /**< ';' : empty controlled statement found; is this what was intended?" */ +#pragma warning(error: 4508) /**< 'function' : function should return a value; void return type assumed */ +#pragma warning(error: 4541) /**< 'identifier' used on polymorphic type 'type' with /GR-; unpredictable behavior may result */ +#pragma warning(error: 4551) /**< function call missing argument list */ +#pragma warning(error: 4553) /**< 'operator' : operator has no effect; did you intend 'operator'? */ +#pragma warning(error: 4700) /**< local variable 'name' used without having been initialized */ +#pragma warning(error: 4706) /**< assignment within conditional expression */ +#pragma warning(error: 4715) /**< 'function' : not all control paths return a value */ +#pragma warning(error: 4761) /**< integral size mismatch in argument : conversion supplied */ +#endif /* WIN32 */ + +#define WBXML_NAMESPACE_SEPARATOR ':' + +/** @} */ + +#endif /* WBXML_INTERNALS_H */ diff --git a/src/wbxml_lists.c b/src/wbxml_lists.c new file mode 100644 index 0000000..2e8bbbc --- /dev/null +++ b/src/wbxml_lists.c @@ -0,0 +1,262 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_lists.c + * @ingroup wbxml_lists + * + * @author Aymerick Jehanne + * @date 02/12/06 + * + * @brief Generic Lists Functions + */ + +#include "wbxml.h" +#include "wbxml_lists.h" + +/** Element of this list */ +typedef struct WBXMLListElt_s +{ + void *item; /**< Element item */ + struct WBXMLListElt_s *next; /**< Next Element */ +} WBXMLListElt; + +/** The Generic List type */ +struct WBXMLList_s +{ + WBXMLListElt *head; /**< Head of the list */ + WBXMLListElt *tail; /**< Tail of the list */ + WB_ULONG len; /**< Number of elements in List */ +}; + +/* Private functions prototypes */ +static WBXMLListElt *wbxml_elt_create_real(void *item); +#define wbxml_elt_create(a) wbxml_mem_cleam(wbxml_elt_create_real(a)) + +static void wbxml_elt_destroy(WBXMLListElt *elt, WBXMLListEltCleaner *destructor); + + +/********************************** + * Public functions + */ + +WBXML_DECLARE(WBXMLList *) wbxml_list_create_real(void) +{ + WBXMLList *list = NULL; + + if ((list = (WBXMLList *) wbxml_malloc(sizeof(WBXMLList))) == NULL) + return NULL; + + list->head = NULL; + list->tail = NULL; + list->len = 0; + + return list; +} + + +WBXML_DECLARE(void) wbxml_list_destroy(WBXMLList *list, WBXMLListEltCleaner *destructor) +{ + WBXMLListElt *elt = NULL, *next = NULL; + + if (list == NULL) + return; + + elt = list->head; + + while (elt != NULL) { + next = elt->next; + wbxml_elt_destroy(elt, destructor); + elt = next; + } + + wbxml_free(list); +} + + +WBXML_DECLARE(WB_ULONG) wbxml_list_len(WBXMLList *list) +{ + if (list == NULL) + return 0; + else + return list->len; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_list_append(WBXMLList *list, void *item) +{ + if (list == NULL) + return FALSE; + + if (list->head == NULL) { + /* Empty list */ + if ((list->head = wbxml_elt_create(item)) == NULL) + return FALSE; + + list->tail = list->head; + } + else { + /* Element is the new Tail */ + if ((list->tail->next = wbxml_elt_create(item)) == NULL) + return FALSE; + + list->tail = list->tail->next; + } + + list->len++; + + return TRUE; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_list_insert(WBXMLList *list, void *item, WB_ULONG pos) +{ + WBXMLListElt *elt = NULL, *prev = NULL, *new_elt = NULL; + WB_ULONG i = 0; + + if (list == NULL) + return FALSE; + + if ((new_elt = wbxml_elt_create(item)) == NULL) + return FALSE; + + /* Empty List */ + if (list->len == 0) { + list->head = new_elt; + list->tail = list->head; + } + else { + /* Insert at Head */ + if (pos == 0) { + /* New Head */ + new_elt->next = list->head; + list->head = new_elt; + } + else { + /* If position is greater than list length, just append it at tail */ + if (pos >= list->len) { + list->tail->next = new_elt; + list->tail = list->tail->next; + } + else { + /* Insert Element */ + elt = list->head; + + for (i=0; inext; + } + + prev->next = new_elt; + new_elt->next = elt; + } + } + } + + list->len++; + + return TRUE; +} + + +WBXML_DECLARE(void *) wbxml_list_get(WBXMLList *list, WB_ULONG index) +{ + WBXMLListElt *elt = NULL; + WB_ULONG i = 0; + + if ((list == NULL) || (index >= wbxml_list_len(list))) + return NULL; + + /* We start to search from head */ + elt = list->head; + + for (i=0; inext; + + return elt->item; +} + + +WBXML_DECLARE(void *) wbxml_list_extract_first(WBXMLList *list) +{ + WBXMLListElt *elt = NULL; + void *result = NULL; + + if ((list == NULL) || (wbxml_list_len(list) == 0)) + return NULL; + + elt = list->head; + result = elt->item; + + if ((list->head = list->head->next) == NULL) + list->tail = NULL; + + wbxml_elt_destroy(elt, NULL); + + list->len--; + + return result; +} + + +/********************************** + * Private functions + */ + +/** + * @brief Create a List Element + * @param item Item of Element to create + * @return The newly created Element, or NULL if not enough memory + * @warning Do NOT use this function directly, use wbxml_list_create() macro instead + */ +static WBXMLListElt *wbxml_elt_create_real(void *item) +{ + WBXMLListElt *elt = NULL; + + if ((elt = (WBXMLListElt *) wbxml_malloc(sizeof(WBXMLListElt))) == NULL) + return NULL; + + elt->item = item; + elt->next = NULL; + + return elt; +} + + +/** + * @brief Destroy a List Element + * @param elt The element to destroy + * @param destructor The Destructor Function to clean Element Item (can be NULL) + */ +static void wbxml_elt_destroy(WBXMLListElt *elt, WBXMLListEltCleaner *destructor) +{ + if (elt == NULL) + return; + + if (destructor != NULL) + destructor(elt->item); + + wbxml_free(elt); +} diff --git a/src/wbxml_lists.h b/src/wbxml_lists.h new file mode 100644 index 0000000..367fa62 --- /dev/null +++ b/src/wbxml_lists.h @@ -0,0 +1,122 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_lists.h + * @ingroup wbxml_lists + * + * @author Aymerick Jehanne + * @date 02/12/06 + * + * @brief Generic Lists Functions + */ + +#ifndef WBXML_LISTS_H +#define WBXML_LISTS_H + +#include "wbxml_mem.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * @brief WBXML Generic List + */ +typedef struct WBXMLList_s WBXMLList; + + +/** @addtogroup wbxml_lists + * @{ + */ + +/** + * @brief A List Element Cleaner Function prototype + */ +typedef void WBXMLListEltCleaner(void *item); + +/** + * @brief Create a List + * @return The newly created List, or NULL if not enough memory + * @warning Do NOT use this function directly, use wbxml_list_create() macro instead + */ +WBXML_DECLARE(WBXMLList *) wbxml_list_create_real(void); +#define wbxml_list_create() wbxml_mem_cleam(wbxml_list_create_real()) + +/** + * @brief Destroy a List + * @param list The List to destroy + * @param destructor The function to destroy an element from list (if NULL, items are not destroyed from list) + */ +WBXML_DECLARE(void) wbxml_list_destroy(WBXMLList *list, WBXMLListEltCleaner *destructor); + +/** + * @brief Get list length + * @param list The List + * @return The List length + */ +WBXML_DECLARE(WB_ULONG) wbxml_list_len(WBXMLList *list); + +/** + * @brief Append an element at end of list + * @param list The List + * @param elt The element to append + * @return TRUE if element appended, FALSE if not enough memory + */ +WBXML_DECLARE(WB_BOOL) wbxml_list_append(WBXMLList *list, void *elt); + +/** + * @brief Append an element to a list + * @param list The List + * @param elt The element to insert + * @param pos The index where to insert this element + * @return TRUE if element appended, FALSE if not enough memory + */ +WBXML_DECLARE(WB_BOOL) wbxml_list_insert(WBXMLList *list, void *elt, WB_ULONG pos); + +/** + * @brief Get an Element from list + * @param list The List + * @param index Index of element to get (index in start starts at '0') + * @return The element, or NULL if not found + */ +WBXML_DECLARE(void *) wbxml_list_get(WBXMLList *list, WB_ULONG index); + +/** + * @brief Extract first element of a List + * @param list The List + * @return The element extracted, or NULL if not found + * @note The element is removed from this list + */ +WBXML_DECLARE(void *) wbxml_list_extract_first(WBXMLList *list); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_LISTS_H */ diff --git a/src/wbxml_log.c b/src/wbxml_log.c new file mode 100644 index 0000000..abc6fdf --- /dev/null +++ b/src/wbxml_log.c @@ -0,0 +1,145 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_log.c + * @ingroup wbxml_log + * + * @author Aymerick Jehanne + * @date 02/12/04 + * + * @brief Log Functions + */ + +#include "wbxml_log.h" + + +#if defined( WBXML_LIB_VERBOSE ) && !defined( WBXML_USE_LEAKTRACKER ) + +#include +#include +#include + + +/** Length of Log Buffer */ +#define WBXML_LOG_FORMAT_SIZE 1024 + + +/* Private Functions Prototypes */ +static void format_log_message(WB_TINY *buf, WB_UTINY type, const WB_TINY *fmt); +static const WB_TINY *get_type(WB_UTINY type); + + +/*************************************************** + * Public Functions + */ + +WBXML_DECLARE(void) wbxml_log_debug(WB_UTINY type, const WB_TINY *fmt, ...) +{ + char buf[WBXML_LOG_FORMAT_SIZE]; + va_list args; + + format_log_message(buf, type, fmt); + + va_start(args, fmt); + vfprintf(stderr, buf, args); + va_end(args); +} + +WBXML_DECLARE(void) wbxml_log_warning(WB_UTINY type, const WB_TINY *fmt, ...) +{ + char buf[WBXML_LOG_FORMAT_SIZE]; + va_list args; + + format_log_message(buf, type, fmt); + + va_start(args, fmt); + vfprintf(stderr, buf, args); + va_end(args); +} + +WBXML_DECLARE(void) wbxml_log_error(WB_UTINY type, const WB_TINY *fmt, ...) +{ + char buf[WBXML_LOG_FORMAT_SIZE]; + va_list args; + + format_log_message(buf, type, fmt); + + va_start(args, fmt); + vfprintf(stderr, buf, args); + va_end(args); +} + + +/*************************************************** + * Private Functions + */ + +/** + * @brief Format a Log Message + * @param buf [out] Resulting formated buffer + * @param type [in] Type of Message + * @param fmt [int] Message to format + */ +static void format_log_message(WB_TINY *buf, WB_UTINY type, const WB_TINY *fmt) +{ + WB_TINY *p, prefix[WBXML_LOG_FORMAT_SIZE]; + + p = prefix; + + sprintf(p, "%s> ", get_type(type)); + + if (WBXML_STRLEN(prefix) + WBXML_STRLEN(fmt) > WBXML_LOG_FORMAT_SIZE / 2) { + sprintf(buf, "(LOG MESSAGE TOO LONG !)\n"); + return; + } + + sprintf(buf, "%s%s\n", prefix, fmt); +} + +/** + * @brief Get a Message Type string + * @param type [in] Type of Message + * @return The string representation of the Message Type + */ +static const WB_TINY *get_type(WB_UTINY type) +{ + switch (type) + { + case WBXML_PARSER: + return "WBXML Parser"; + + case WBXML_ENCODER: + return "WBXML Encoder"; + + case WBXML_CONV: + return "WBXML Converter"; + + default: + return "WBXML Unknown"; + } +} + +#endif /* WBXML_LIB_VERBOSE */ diff --git a/src/wbxml_log.h b/src/wbxml_log.h new file mode 100644 index 0000000..7e022b9 --- /dev/null +++ b/src/wbxml_log.h @@ -0,0 +1,110 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_log.h + * @ingroup wbxml_log + * + * @author Aymerick Jehanne + * @date 02/12/04 + * + * @brief Log Functions + */ + +#ifndef WBXML_LOG_H +#define WBXML_LOG_H + +#include "wbxml.h" + +#ifdef WBXML_USE_LEAKTRACKER +#include "leaktrack.h" +#include "lt_log.h" +#endif /* WBXML_USE_LEAKTRACKER */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_log + * @{ + */ + +/* Compilation Flags: WBXML_LIB_VERBOSE / WBXML_USE_LEAKTRACKER */ + +/* Log Macros */ +#if defined( WBXML_LIB_VERBOSE ) +#if defined( WBXML_USE_LEAKTRACKER ) +#define WBXML_DEBUG(msg) lt_log msg +#define WBXML_WARNING(msg) lt_log msg +#define WBXML_ERROR(msg) lt_log msg +#define WBXML_PARSER 0x00 +#define WBXML_ENCODER 0x00 +#define WBXML_CONV 0x00 +#else /* !WBXML_USE_LEAKTRACKER */ +#define WBXML_DEBUG(msg) wbxml_log_debug msg +#define WBXML_WARNING(msg) wbxml_log_warning msg +#define WBXML_ERROR(msg) wbxml_log_error msg +#define WBXML_PARSER 0x01 +#define WBXML_ENCODER 0x02 +#define WBXML_CONV 0x03 +#endif /* WBXML_USE_LEAKTRACKER */ +#else /* !WBXML_LIB_VERBOSE */ +#define WBXML_DEBUG(msg) +#define WBXML_WARNING(msg) +#define WBXML_ERROR(msg) +#endif /* WBXML_LIB_VERBOSE */ + + +/** + * @brief Log a DEBUG message + * @param type Type of Message + * @param fmt Message to log + * @note Do NOT use this function directly, use WBXML_DEBUG() macro instead + */ +WBXML_DECLARE(void) wbxml_log_debug(WB_UTINY type, const WB_TINY *fmt, ...); + +/** + * @brief Log a WARNING message + * @param type Type of Message + * @param fmt Message to log + * @note Do NOT use this function directly, use WBXML_WARNING() macro instead + */ +WBXML_DECLARE(void) wbxml_log_warning(WB_UTINY type, const WB_TINY *fmt, ...); + +/** + * @brief Log an ERROR message + * @param type Type of Message + * @param fmt Message to log + * @note Do NOT use this function directly, use WBXML_ERROR() macro instead + */ +WBXML_DECLARE(void) wbxml_log_error(WB_UTINY type, const WB_TINY *fmt, ...); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_LOG_H */ diff --git a/src/wbxml_mem.c b/src/wbxml_mem.c new file mode 100644 index 0000000..0211363 --- /dev/null +++ b/src/wbxml_mem.c @@ -0,0 +1,80 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_mem.c + * @ingroup wbxml_mem + * + * @author Aymerick Jehanne + * @date 02/11/24 + * + * @brief Memory Functions + */ + +#include "wbxml_mem.h" + + +/*************************************************** + * Public Functions + */ + +WBXML_DECLARE(void *) wbxml_malloc(size_t size) +{ +#ifdef WBXML_USE_LEAKTRACKER + return lt_malloc(size); +#else + return malloc(size); +#endif +} + + +WBXML_DECLARE(void) wbxml_free(void *memblock) +{ +#ifdef WBXML_USE_LEAKTRACKER + lt_free(memblock); +#else + free(memblock); +#endif +} + + +WBXML_DECLARE(void *) wbxml_realloc(void *memblock, size_t size) +{ +#ifdef WBXML_USE_LEAKTRACKER + return lt_realloc(memblock, size); +#else + return realloc(memblock, size); +#endif +} + + +WBXML_DECLARE(char *) wbxml_strdup(const char *str) +{ +#ifdef WBXML_USE_LEAKTRACKER + return lt_strdup(str); +#else + return strdup(str); +#endif +} diff --git a/src/wbxml_mem.h b/src/wbxml_mem.h new file mode 100644 index 0000000..364bad2 --- /dev/null +++ b/src/wbxml_mem.h @@ -0,0 +1,91 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_mem.h + * @ingroup wbxml_mem + * + * @author Aymerick Jehanne + * @date 02/07/01 + * + * @brief Memory Functions + */ + +#ifndef WBXML_MEM_H +#define WBXML_MEM_H + +#include "wbxml.h" + +#ifdef WBXML_USE_LEAKTRACKER +#include "leaktrack.h" +#include "lt_log.h" +#define wbxml_mem_cleam(ptr) (lt_claim_area(ptr)) +#else /* WBXML_USE_LEAKTRACKER */ +#define wbxml_mem_cleam(ptr) (ptr) +#endif /* WBXML_USE_LEAKTRACKER */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_mem + * @{ + */ + +/** + * @brief Alloc a Memory Block + * @param size Size of Memory to alloc + * @return The newly mlloced Memory Block, or NULL if not enough memory + */ +WBXML_DECLARE(void *) wbxml_malloc(size_t size); + +/** + * @brief Free a Memory Block + * @param memblock The Memory Block to free + */ +WBXML_DECLARE(void) wbxml_free(void *memblock); + +/** + * @brief Realloc a Memory Block + * @param memblock The Memory Block to realloc + * @param size Size of Memory to realloc + * @return The newly realloced Memory Block, or NULL if not enough memory + */ +WBXML_DECLARE(void *) wbxml_realloc(void *memblock, size_t size); + +/** + * @brief Duplicate a C String + * @param str The C String to duplicate + * @return The newly duplicated C String, or NULL if not enough memory + */ +WBXML_DECLARE(char *) wbxml_strdup(const char *str); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_MEM_H */ diff --git a/src/wbxml_parser.c b/src/wbxml_parser.c new file mode 100644 index 0000000..9f27911 --- /dev/null +++ b/src/wbxml_parser.c @@ -0,0 +1,2922 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2009-2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_parser.c + * @ingroup wbxml_parser + * + * @author Aymerick Jehanne + * @date 02/03/12 + * + * @brief WBXML Parser - Parse a WBXML document and call user defined Callbacks + * + * @todo Handle correctly charset + * + * @note WBXML Versions Differences: + * - WBXML 1.2: - No differences with WBXML 1.3, except a clarification in BNF for 'LITERAL' handling + * - WBXML 1.1: - No Switch Page mecanism + * - An Attribute value can't be "opaque" + * - WBXML 1.0: - No 'charset' handling + * - No 'opaque' support + * - A strange 'body' rule description in BNF (just forget it). + */ + +#include "wbxml_parser.h" +#include "wbxml_log.h" +#include "wbxml_internals.h" +#include "wbxml_base64.h" +#include "wbxml_charset.h" +#include + + +/* Memory management related defines */ +#define WBXML_PARSER_MALLOC_BLOCK 5000 +#define WBXML_PARSER_STRING_TABLE_MALLOC_BLOCK 200 +#define WBXML_PARSER_ATTR_VALUE_MALLOC_BLOCK 100 + +/** Set it to '1' for Best Effort mode */ +#define WBXML_PARSER_BEST_EFFORT 1 + +/** For unknown Tag Name or Attribute Name (in Best Effort Mode) */ +#define WBXML_PARSER_UNKNOWN_STRING ((WB_UTINY *)"unknown") + +/** + * @brief The WBXML Application Token types + */ +typedef enum WBXMLTokenType_e { + WBXML_TAG_TOKEN, /**< Tag token */ + WBXML_ATTR_TOKEN /**< Attribute token */ +} WBXMLTokenType; + + +/** + * @brief The WBXML Parser + * @warning For now 'current_tag' field is only used for WV Content Parsing. And for this use, it works. + * But this field is reset after End Tag, and as there is no Linked List mecanism, this is bad for + * cascading elements: we don't fill this field with parent Tag when parsing End Tag. + */ +struct WBXMLParser_s { + void *user_data; /**< User Data */ + WBXMLContentHandler *content_hdl; /**< Content Handlers Callbacks */ + WBXMLBuffer *wbxml; /**< The wbxml we are parsing */ + WBXMLBuffer *strstbl; /**< String Table specified in WBXML document */ + const WBXMLLangEntry *langTable; /**< Current document Language Table */ + const WBXMLLangEntry *mainTable; /**< Main WBXML Languages Table */ + const WBXMLTagEntry *current_tag; /**< Current Tag */ + + WBXMLLanguage lang_forced; /**< Language forced by User */ + WB_ULONG public_id; /**< Public ID specified in WBXML document */ + WB_LONG public_id_index; /**< If Public ID is a String Table reference, + this is the index defined in the strtbl */ + WBXMLCharsetMIBEnum charset; /**< Charset of WBXML document */ + WBXMLCharsetMIBEnum meta_charset; /**< Meta-info provided by user: only used if + Charset is not specified in WBXML document */ + WB_ULONG pos; /**< Position of parsing curser in wbxml */ + WBXMLVersion version; /**< WBXML Version field specified in WBXML document */ + WB_UTINY tagCodePage; /**< Current Tag Code Page */ + WB_UTINY attrCodePage; /**< Current Attribute Code Page */ +}; + + + +/*************************************************** + * Private Functions prototypes + */ + +/* WBXML Parser functions */ +static void wbxml_parser_reinit(WBXMLParser *parser); + +/* Check functions */ +static WB_BOOL is_token(WBXMLParser *parser, WB_UTINY token); +static WB_BOOL is_literal(WBXMLParser *parser); +static WB_BOOL is_attr_value(WBXMLParser *parser); +static WB_BOOL is_string(WBXMLParser *parser); +static WB_BOOL is_extension(WBXMLParser *parser); +static WB_BOOL check_public_id(WBXMLParser *parser); + +/* Parse functions */ +static WBXMLError parse_version(WBXMLParser *parser); +static WBXMLError parse_publicid(WBXMLParser *parser); +static WBXMLError parse_charset(WBXMLParser *parser); +static WBXMLError parse_strtbl(WBXMLParser *parser); +static WBXMLError parse_body(WBXMLParser *parser); + +static WBXMLError parse_pi(WBXMLParser *parser); +static WBXMLError parse_element(WBXMLParser *parser); +static void free_attrs_table(WBXMLAttribute **attrs); + +static WBXMLError parse_switch_page(WBXMLParser *parser, WBXMLTokenType code_space); +static WBXMLError parse_stag(WBXMLParser *parser, WB_UTINY *tag, WBXMLTag **element); +static WBXMLError parse_tag(WBXMLParser *parser, WB_UTINY *tag, WBXMLTag **element); +static WBXMLError parse_attribute(WBXMLParser *parser, WBXMLAttribute **attr); +static WBXMLError parse_content(WBXMLParser *parser, WBXMLBuffer **result); + +static WBXMLError parse_string(WBXMLParser *parser, WBXMLBuffer **result); +static WBXMLError parse_extension(WBXMLParser *parser, WBXMLTokenType code_space, WBXMLBuffer **result); +static WBXMLError parse_entity(WBXMLParser *parser, WBXMLBuffer **result); +static WBXMLError parse_opaque(WBXMLParser *parser, WBXMLBuffer **result); + +static WBXMLError parse_literal(WBXMLParser *parser, WB_UTINY *tag, WBXMLBuffer **result); + +static WBXMLError parse_attr_start(WBXMLParser *parser, WBXMLAttributeName **name, const WB_UTINY **value); +static WBXMLError parse_attr_value(WBXMLParser *parser, WBXMLBuffer **result); + +static WBXMLError parse_termstr(WBXMLParser *parser, WBXMLBuffer **result); +static WBXMLError parse_inline(WBXMLParser *parser, WBXMLBuffer **result); +static WBXMLError parse_tableref(WBXMLParser *parser, WBXMLBuffer **result); +static WBXMLError parse_entcode(WBXMLParser *parser, WB_ULONG *result); + +static WBXMLError get_strtbl_reference(WBXMLParser *parser, WB_ULONG index, WBXMLBuffer **result); + +/* Basic Types Parse functions */ +static WBXMLError parse_uint8(WBXMLParser *parser, WB_UTINY *result); +static WBXMLError parse_mb_uint32(WBXMLParser *parser, WB_ULONG *result); + +/* Language Specific Decoding Functions */ +static WBXMLError decode_base64_value(WBXMLBuffer **data); + +#if defined( WBXML_SUPPORT_SI ) || defined( WBXML_SUPPORT_EMN ) +static WBXMLError decode_datetime(WBXMLBuffer *buff); +#endif /* WBXML_SUPPORT_SI || WBXML_SUPPORT_EMN */ + +static WBXMLError decode_opaque_content(WBXMLParser *parser, WBXMLBuffer **data); +static WBXMLError decode_opaque_attr_value(WBXMLParser *parser, WBXMLBuffer **data); + +#if defined( WBXML_SUPPORT_WV ) +static WBXMLError decode_wv_content(WBXMLParser *parser, WBXMLBuffer **data); +static WBXMLError decode_wv_integer(WBXMLBuffer **data); +static WBXMLError decode_wv_datetime(WBXMLBuffer **data); +#endif /* WBXML_SUPPORT_WV */ + +/* Macro for error handling */ +#define CHECK_ERROR if (ret != WBXML_OK) return ret; + + +/*************************************************** + * Public Functions + */ + +WBXML_DECLARE(WBXMLParser *) wbxml_parser_create(void) +{ + WBXMLParser *parser = NULL; + + parser = (WBXMLParser *) wbxml_malloc(sizeof(WBXMLParser)); + if (parser == NULL) { + return NULL; + } + + parser->wbxml = NULL; + parser->user_data = NULL; + parser->content_hdl = NULL; + parser->strstbl = NULL; + parser->langTable = NULL; + + /* Default Main WBXML Languages Table */ + parser->mainTable = wbxml_tables_get_main(); + + parser->current_tag = NULL; + + parser->lang_forced = WBXML_LANG_UNKNOWN; + parser->public_id = WBXML_PUBLIC_ID_UNKNOWN; + parser->public_id_index = -1; + parser->charset = WBXML_CHARSET_UNKNOWN; + parser->meta_charset = WBXML_CHARSET_UNKNOWN; + parser->version = WBXML_VERSION_UNKNOWN; + + parser->pos = 0; + parser->tagCodePage = 0; + parser->attrCodePage = 0; + + return parser; +} + + +WBXML_DECLARE(void) wbxml_parser_destroy(WBXMLParser *parser) +{ + if (parser == NULL) + return; + + wbxml_buffer_destroy(parser->wbxml); + wbxml_buffer_destroy(parser->strstbl); + + wbxml_free(parser); +} + + +WBXML_DECLARE(WBXMLError) wbxml_parser_parse(WBXMLParser *parser, WB_UTINY *wbxml, WB_ULONG wbxml_len) +{ + WBXMLError ret = WBXML_OK; + + if (parser == NULL) + return WBXML_ERROR_NULL_PARSER; + + if ((wbxml == NULL) || (wbxml_len <= 0)) + return WBXML_ERROR_EMPTY_WBXML; + + /* Reinitialize WBXML Parser */ + wbxml_parser_reinit(parser); + + parser->wbxml = wbxml_buffer_create(wbxml, wbxml_len, WBXML_PARSER_MALLOC_BLOCK); + if (parser->wbxml == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* WBXML Version */ + ret = parse_version(parser); + CHECK_ERROR + + if ((WB_UTINY)parser->version > WBXML_VERSION_13) { + WBXML_WARNING((WBXML_PARSER, "This library only supports WBXML %s.", WBXML_VERSION_TEXT_13)); + } + + /* WBXML Public ID */ + ret = parse_publicid(parser); + CHECK_ERROR + + /* Ignore Document Public ID if user has forced use of another Public ID */ + if (parser->lang_forced != WBXML_LANG_UNKNOWN) + parser->public_id = wbxml_tables_get_wbxml_publicid(wbxml_tables_get_main(), parser->lang_forced); + + /* No charset in WBXML 1.0 */ + if (parser->version != WBXML_VERSION_10) { + ret = parse_charset(parser); + CHECK_ERROR + } + + /* Check charset */ + if (parser->charset == WBXML_CHARSET_UNKNOWN) { + if (parser->meta_charset != WBXML_CHARSET_UNKNOWN) { + /* Use meta-information provided by user */ + parser->charset = parser->meta_charset; + + WBXML_DEBUG((WBXML_PARSER, + "Using provided meta charset: %ld", + parser->meta_charset)); + } + else { + /* Default Charset Encoding: UTF-8 */ + parser->charset = WBXML_PARSER_DEFAULT_CHARSET; + + WBXML_WARNING((WBXML_PARSER, + "No charset information found, using default : %x", + WBXML_PARSER_DEFAULT_CHARSET)); + } + } + + /* WBXML String Table */ + ret = parse_strtbl(parser); + CHECK_ERROR + + /* Now that we have parsed String Table, we can check Public ID */ + if (!check_public_id(parser)) { + WBXML_ERROR((WBXML_PARSER, "PublicID not found")); + return WBXML_ERROR_UNKNOWN_PUBLIC_ID; + } + + /* Call to WBXMLStartDocumentHandler */ + if ((parser->content_hdl != NULL) && (parser->content_hdl->start_document_clb != NULL)) + parser->content_hdl->start_document_clb(parser->user_data, parser->charset, parser->langTable); + + /* WBXML Body */ + ret = parse_body(parser); + CHECK_ERROR + + /* Call to WBXMLEndDocumentHandler */ + if ((parser->content_hdl != NULL) && (parser->content_hdl->end_document_clb != NULL)) + parser->content_hdl->end_document_clb(parser->user_data); + + return ret; +} + + +WBXML_DECLARE(void) wbxml_parser_set_user_data(WBXMLParser *parser, void *user_data) +{ + if (parser != NULL) + parser->user_data = user_data; +} + + +WBXML_DECLARE(void) wbxml_parser_set_content_handler(WBXMLParser *parser, WBXMLContentHandler *content_handler) +{ + if (parser != NULL) + parser->content_hdl = content_handler; +} + + +WBXML_DECLARE(void) wbxml_parser_set_main_table(WBXMLParser *parser, const WBXMLLangEntry *main_table) +{ + if (parser != NULL) + parser->mainTable = main_table; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_parser_set_language(WBXMLParser *parser, WBXMLLanguage lang) +{ + if (parser != NULL) { + parser->lang_forced = lang; + return TRUE; + } + + return FALSE; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_parser_set_meta_charset(WBXMLParser *parser, + WBXMLCharsetMIBEnum charset) +{ + if ( parser != NULL ) { + parser->meta_charset = charset; + return TRUE; + } + + return FALSE; +} + + +WBXML_DECLARE(WB_ULONG) wbxml_parser_get_wbxml_public_id(WBXMLParser *parser) +{ + if ((parser != NULL) && (parser->langTable != NULL) && (parser->langTable->publicID != NULL)) + return parser->langTable->publicID->wbxmlPublicID; + else + return WBXML_PUBLIC_ID_UNKNOWN; +} + + +WBXML_DECLARE(const WB_UTINY *) wbxml_parser_get_xml_public_id(WBXMLParser *parser) +{ + if ((parser != NULL) && (parser->langTable != NULL) && (parser->langTable->publicID != NULL)) + return (const WB_UTINY *) parser->langTable->publicID->xmlPublicID; + else + return NULL; +} + + +WBXML_DECLARE(WBXMLVersion) wbxml_parser_get_wbxml_version(WBXMLParser *parser) +{ + if (parser != NULL) + return parser->version; + else + return WBXML_VERSION_UNKNOWN; +} + + +WBXML_DECLARE(WB_LONG) wbxml_parser_get_current_byte_index(WBXMLParser *parser) +{ + if (parser != NULL) + return parser->pos - 1; + else + return 0; +} + + +/*************************************************** + * Private Functions + */ + +/************************** + * WBXML Parser functions + */ + +/** + * @brief Reinitialize a WBXML Parser + * @param parser The WBXMLParser to reinitialize + * @note Only reinitialize internal fields of parser, and so keep User Data + * and Content Handler pointers. + */ +static void wbxml_parser_reinit(WBXMLParser *parser) +{ + if (parser == NULL) + return; + + wbxml_buffer_destroy(parser->wbxml); + parser->wbxml = NULL; + + wbxml_buffer_destroy(parser->strstbl); + parser->strstbl = NULL; + + parser->langTable = NULL; + parser->current_tag = NULL; + + parser->public_id = WBXML_PUBLIC_ID_UNKNOWN; + parser->public_id_index = -1; + parser->charset = WBXML_CHARSET_UNKNOWN; + parser->version = WBXML_VERSION_UNKNOWN; + + parser->pos = 0; + parser->tagCodePage = 0; + parser->attrCodePage = 0; +} + + +/****************** + * Check functions + */ + +/** + * @brief Check if current byte a specified WBXML token + * @param parser The WBXML Parser + * @param token The WBXML token + * @return TRUE is current byte is the specified token, FALSE otherwise + */ +static WB_BOOL is_token(WBXMLParser *parser, WB_UTINY token) +{ + WB_UTINY result; + + if (!wbxml_buffer_get_char(parser->wbxml, parser->pos, &result)) + return FALSE; + + return (WB_BOOL) (result == token); +} + + +/** + * @brief Check if current byte is a WBXML literalTag token + * @param parser The WBXML Parser + * @return TRUE is current byte is a literalTag token, FALSE otherwise + */ +static WB_BOOL is_literal(WBXMLParser *parser) +{ + WB_UTINY result; + + if (!wbxml_buffer_get_char(parser->wbxml, parser->pos, &result)) + return FALSE; + + return (WB_BOOL) ((result == WBXML_LITERAL) || (result == WBXML_LITERAL_A) || (result == WBXML_LITERAL_C) || (result == WBXML_LITERAL_AC)); +} + + +/** + * @brief Check if next token to parse is an Attribute Value + * @param parser The WBXML Parser + * @return TRUE if next token to parse is an Attribute Value, FALSE otherwise + * @note attrValue = ([switchPage] ATTRVALUE | string | extension | entity | opaque) + */ +static WB_BOOL is_attr_value(WBXMLParser *parser) +{ + WB_UTINY cur_byte, next_byte; + + /* Get current byte */ + if (!wbxml_buffer_get_char(parser->wbxml, parser->pos, &cur_byte)) + return FALSE; + + /* If current byte is a switch page, check that following token is an Attribute Value token */ + if (is_token(parser, WBXML_SWITCH_PAGE)) { + if (!wbxml_buffer_get_char(parser->wbxml, parser->pos + 2, &next_byte)) + return FALSE; + + /* Attribute Value is greater than or equal to 128 */ + if ((next_byte & 0x80) == 0x80) + return TRUE; + } + + /* Else, check current byte is an Attribute Value, a string, an extension, an entity or an opaque */ + if (((cur_byte & 0x80) == 0x80) || + (is_string(parser)) || + (is_extension(parser)) || + (is_token(parser, WBXML_ENTITY)) || + (is_token(parser, WBXML_OPAQUE))) + return TRUE; + + return FALSE; +} + + +/** + * @brief Check if current byte is a string + * @param parser The WBXML Parser + * @return TRUE if current byte is a string, FALSE otherwise + */ +static WB_BOOL is_string(WBXMLParser *parser) +{ + return (WB_BOOL) (is_token(parser, WBXML_STR_I) || is_token(parser, WBXML_STR_T)); +} + + +/** + * @brief Check if current byte is an extension + * @param parser The WBXML Parser + * @return TRUE if current byte is an extension, FALSE otherwise + */ +static WB_BOOL is_extension(WBXMLParser *parser) +{ + WB_UTINY cur_byte; + + /* If current byte is a switch page, check the following token */ + if (is_token(parser, WBXML_SWITCH_PAGE)) { + if (!wbxml_buffer_get_char(parser->wbxml, parser->pos + 2, &cur_byte)) + return FALSE; + } + else { + if (!wbxml_buffer_get_char(parser->wbxml, parser->pos, &cur_byte)) + return FALSE; + } + + return (WB_BOOL) ((cur_byte == WBXML_EXT_I_0) || (cur_byte == WBXML_EXT_I_1) || (cur_byte == WBXML_EXT_I_2) || + (cur_byte == WBXML_EXT_T_0) || (cur_byte == WBXML_EXT_T_1) || (cur_byte == WBXML_EXT_T_2) || + (cur_byte == WBXML_EXT_0) || (cur_byte == WBXML_EXT_1) || (cur_byte == WBXML_EXT_2)); +} + + +/** + * @brief Check the Public ID + * @param parser The WBXML Parser + * @return TRUE if Public ID is found, FALSE otherwise + */ +static WB_BOOL check_public_id(WBXMLParser *parser) +{ + WBXMLBuffer *public_id = NULL; + WB_LONG index = 0; + WBXMLError ret; + + WBXML_DEBUG((WBXML_PARSER, "\t Checking PublicID")); + + /* First check if we can figure out the Public ID */ + if ((parser->lang_forced == WBXML_LANG_UNKNOWN) && + (parser->public_id == WBXML_PUBLIC_ID_UNKNOWN) && + (parser->public_id_index == -1)) + { + return FALSE; + } + + + /******************************************************** + * Case 1: Language is forced by user + */ + + if (parser->lang_forced != WBXML_LANG_UNKNOWN) { + /* Search Language Entry */ + while (parser->mainTable[index].langID != WBXML_LANG_UNKNOWN) { + if (parser->mainTable[index].langID == parser->lang_forced) { + parser->langTable = &(parser->mainTable[index]); + + WBXML_DEBUG((WBXML_PARSER, "\t Language Forced - PublicID : '%s'", parser->mainTable[index].publicID->xmlPublicID)); + + return TRUE; + } + + index++; + } + } + + + /******************************************************** + * Case 2: Public ID is a normal token + * (found in WBXML Document, or forced by user) + */ + + if (parser->public_id != WBXML_PUBLIC_ID_UNKNOWN) { + WBXML_DEBUG((WBXML_PARSER, "\t PublicID token: 0x%X", parser->public_id)); + + /* Search Public ID Table */ + while (parser->mainTable[index].publicID != NULL) { + if (parser->mainTable[index].publicID->wbxmlPublicID == parser->public_id) { + parser->langTable = &(parser->mainTable[index]); + + WBXML_DEBUG((WBXML_PARSER, "\t PublicID : '%s'", parser->mainTable[index].publicID->xmlPublicID)); + + return TRUE; + } + + index++; + } + } + + + /******************************************************** + * Case 3: Public ID referenced in String Table + */ + if (parser->public_id_index != -1) { + WBXML_DEBUG((WBXML_PARSER, "\t PublicID is in String Table (index: 0x%X)", parser->public_id_index)); + + ret = get_strtbl_reference(parser, (WB_ULONG) parser->public_id_index, &public_id); + if (ret != WBXML_OK) { + WBXML_ERROR((WBXML_PARSER, "Bad publicID reference in string table. %s", wbxml_errors_string(ret))); + return FALSE; + } + + WBXML_DEBUG((WBXML_PARSER, "\t PublicID : '%s'", wbxml_buffer_get_cstr(public_id))); + + /* Search Public ID Table */ + while (parser->mainTable[index].publicID != NULL) + { + if ((parser->mainTable[index].publicID->xmlPublicID != NULL) && + (WBXML_STRCASECMP(parser->mainTable[index].publicID->xmlPublicID, wbxml_buffer_get_cstr(public_id)) == 0)) + { + parser->langTable = &(parser->mainTable[index]); + /* parser->public_id = parser->mainTable[index].publicID->wbxmlPublicID; */ + + wbxml_buffer_destroy(public_id); + return TRUE; + } + + index++; + } + + /* Clean up */ + wbxml_buffer_destroy(public_id); + } + + /* Public ID not found in Tables */ + return FALSE; +} + + + +/*************************** + * WBXML Parse functions + */ + +/** + * @brief Parse WBXML version + * @param parser The WBXML Parser + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note version = u_int8 + */ +static WBXMLError parse_version(WBXMLParser *parser) +{ + WBXMLError ret = WBXML_OK; + + /* Initialize version: 1.0 + * + * Do NOT keep 'WBXML_VERSION_UNKNOWN' (0xffffffff) because only one byte will change. + * (for example, if the version is 0x02, then parser->version will be 0xffffff02) + */ + WB_UTINY version = WBXML_VERSION_10; + + if ((ret = parse_uint8(parser, &version)) != WBXML_OK) + return ret; + + parser->version = version; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsed version: 1.%d", parser->pos - 1, parser->version)); + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML public id + * @param parser The WBXML Parser + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note publicid = mb_u_int32 | ( zero index ) + * @note index = mb_u_int32 + */ +static WBXMLError parse_publicid(WBXMLParser *parser) +{ + WB_UTINY public_id; + WBXMLError ret; + + if (!wbxml_buffer_get_char(parser->wbxml, parser->pos, &public_id)) + return WBXML_ERROR_END_OF_BUFFER; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsed public id value: '0x%X'", parser->pos, public_id)); + + if (public_id == 0x00) { + parser->pos++; + + /* Get index (we will retrieve the Public ID later from string table) */ + ret = parse_mb_uint32(parser, (WB_ULONG *)&parser->public_id_index); + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsed public id index: '0x%x'", parser->pos-1, parser->public_id_index)); + return ret; + } + else { + /* Get Public ID */ + ret = parse_mb_uint32(parser, &parser->public_id); + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsed public id: '0x%x'", parser->pos-1, parser->public_id)); + return ret; + } +} + + +/** + * @brief Parse WBXML charset + * @param parser The WBXML Parser + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note charset = mb_u_int32 + * @note "The binary XML format contains a representation of the XML document character encoding. + * This is the WBXML equivalent of the XML document format encoding attribute, + * which is specified in the ?xml processing instruction. The character set is encoded as + * a multi-byte positive integer value, representing the IANA-assigned MIB number for + * a character set. A value of zero indicates an unknown document encoding. In the case of + * an unknown encoding, transport meta-information should be used to determine the character + * encoding. If transport meta-information is unavailable, the default encoding of UTF-8 + * should be assumed." + */ +static WBXMLError parse_charset(WBXMLParser *parser) +{ + /* definitions first ... or some compilers don't like it */ + const char *charset_name = NULL; + +#if defined( WBXML_LIB_VERBOSE ) + WB_ULONG startpos = parser->pos; +#endif /* WBXML_LIB_VERBOSE */ + + unsigned int charset = 0; + WBXMLError ret = parse_mb_uint32(parser, &charset); + + if (ret != WBXML_OK) { + WBXML_DEBUG((WBXML_PARSER, "(%d) failed to parse character set", startpos)); + return ret; + } + + if (charset == 0) { + WBXML_DEBUG((WBXML_PARSER, "(%d) The character set is zero.", startpos)); + if (parser->meta_charset != WBXML_CHARSET_UNKNOWN) { + /* use character set from transport meta-information */ + WBXML_DEBUG((WBXML_PARSER, "(%d) Using charset from meta-info ...%d.", startpos, parser->meta_charset)); + charset = parser->meta_charset; + } else { + /* default encoding is UTF-8 */ + WBXML_DEBUG((WBXML_PARSER, "(%d) Enabling the default character set ... UTF-8.", startpos)); + charset = WBXML_CHARSET_UTF_8; + } + } + + if (!wbxml_charset_get_name(charset, &charset_name)) { + WBXML_DEBUG((WBXML_PARSER, "(%d) failed to get character set name", charset)); + return WBXML_ERROR_CHARSET_NOT_FOUND; + } + parser->charset = (WBXMLCharsetMIBEnum) charset; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsed charset: '0x%X'", startpos, parser->charset)); + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML string table + * @param parser The WBXML Parser + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note strtbl = length *byte + * @note length = mb_u_int32 + */ +static WBXMLError parse_strtbl(WBXMLParser *parser) +{ + WB_UTINY *data = NULL; + WB_ULONG strtbl_len = 0; + WB_UTINY end_char = 0; + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing strtbl", parser->pos)); + + /* Get String Table Length */ + ret = parse_mb_uint32(parser, &strtbl_len); + if (ret != WBXML_OK) + return WBXML_ERROR_END_OF_BUFFER; + + if (strtbl_len > 0) { + /* Check this string table length */ + if (strtbl_len > wbxml_buffer_len(parser->wbxml) - parser->pos) + return WBXML_ERROR_STRTBL_LENGTH; + + /* Get String Table */ + data = wbxml_buffer_get_cstr(parser->wbxml); + parser->strstbl = wbxml_buffer_create(data + parser->pos, strtbl_len, WBXML_PARSER_STRING_TABLE_MALLOC_BLOCK); + if (parser->strstbl == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /** @todo Damned ! Check the charset ! This may not be a simple NULL terminated string ! */ + + /* Some phones doesn't terminate the String Table with a null char... let's correct this */ + if (!wbxml_buffer_get_char(parser->strstbl, + wbxml_buffer_len(parser->strstbl) - 1, + &end_char)) + { + return WBXML_ERROR_INTERNAL; + } + + /* If there is a correctly terminated string + * then there is no reason to do anything. + */ + if (end_char != '\0') { + WBXML_DEBUG((WBXML_PARSER, " Adding NULL bytes to strtbl.")); + /* A terminating NULL byte is not enough today. + * There exists character sets with a fixed length of bytes. + * Such strings must be terminated with a complete NULL character. + * ASCII => 1 byte + * UTF-8 => 1 byte + * UTF-16 => 2 bytes + * UTF-32 => 4 bytes (I hope so) + * UCS-2 => 2 bytes + * I hope four NULL bytes are enough for all cases. + */ + if (!wbxml_buffer_append_char(parser->strstbl, '\0')) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + if (!wbxml_buffer_append_char(parser->strstbl, '\0')) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + if (!wbxml_buffer_append_char(parser->strstbl, '\0')) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + if (!wbxml_buffer_append_char(parser->strstbl, '\0')) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + parser->pos = parser->pos + strtbl_len; + } + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML body + * @param parser The WBXML Parser + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note body = *pi element *pi + */ +static WBXMLError parse_body(WBXMLParser *parser) +{ + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing body", parser->pos)); + + while (is_token(parser, WBXML_PI)) { + if ((ret = parse_pi(parser)) != WBXML_OK) + return ret; + } + + if ((ret = parse_element(parser)) != WBXML_OK) + return ret; + + while (is_token(parser, WBXML_PI)) { + if ((ret = parse_pi(parser)) != WBXML_OK) + return ret; + } + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML pi + * @param parser The WBXML Parser + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note pi = PI attrStart *attrValue END + */ +static WBXMLError parse_pi(WBXMLParser *parser) +{ + WBXMLAttributeName *attr_name = NULL; + const WB_UTINY *start_value = NULL; + WBXMLBuffer *attr_value = NULL; + WBXMLBuffer *tmp_value = NULL; + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing PI", parser->pos)); + + /* Skip PI */ + parser->pos++; + + /* Parse attrStart */ + if ((ret = parse_attr_start(parser, + &attr_name, + &start_value)) != WBXML_OK) + { + return ret; + } + + if (start_value != NULL ) { + /* Create a buffer from attribute start value */ + attr_value = wbxml_buffer_create(start_value, + WBXML_STRLEN(start_value), + WBXML_PARSER_ATTR_VALUE_MALLOC_BLOCK); + } + else { + /* Create an empty buffer */ + attr_value = wbxml_buffer_create(NULL, + 0, + WBXML_PARSER_ATTR_VALUE_MALLOC_BLOCK); + } + + if (attr_value == NULL) { + /* Memory error */ + wbxml_attribute_name_destroy(attr_name); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + + /* Parse *attrValue */ + while (!is_token(parser, WBXML_END)) { + /* Parse attrValue */ + if ((ret = parse_attr_value(parser, &tmp_value)) != WBXML_OK) { + wbxml_attribute_name_destroy(attr_name); + wbxml_buffer_destroy(attr_value); + return ret; + } + + /* Append to main attribute value buffer */ + if (!wbxml_buffer_append(attr_value, tmp_value)) { + wbxml_attribute_name_destroy(attr_name); + wbxml_buffer_destroy(attr_value); + wbxml_buffer_destroy(tmp_value); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + wbxml_buffer_destroy(tmp_value); + tmp_value = NULL; + } + + /* Skip END */ + parser->pos++; + + /* Append NULL char to attr value */ + if (wbxml_buffer_len(attr_value) > 0) { + if (!wbxml_buffer_append_char(attr_value, '\0')) { + wbxml_attribute_name_destroy(attr_name); + wbxml_buffer_destroy(attr_value); + + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + + /* Callback WBXMLProcessingInstructionHandler */ + if ((parser->content_hdl != NULL) && + (parser->content_hdl->pi_clb != NULL)) + { + parser->content_hdl->pi_clb(parser->user_data, + wbxml_attribute_name_get_xml_name(attr_name), + wbxml_buffer_get_cstr(attr_value)); + } + + wbxml_attribute_name_destroy(attr_name); + wbxml_buffer_destroy(attr_value); + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML element + * @param parser The WBXML Parser + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note element = ([switchPage] stag) [ 1*attribute END ] [ *content END ] + */ +static WBXMLError parse_element(WBXMLParser *parser) +{ + WBXMLTag *element = NULL; + WBXMLAttribute *attr = NULL; + WBXMLAttribute **attrs = NULL; + WBXMLBuffer *content = NULL; + + WB_ULONG attrs_nb = 0; + WBXMLError ret = WBXML_OK; + WB_UTINY tag = 0; + WB_BOOL is_empty = FALSE; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing element", parser->pos)); + + if (is_token(parser, WBXML_SWITCH_PAGE)) { + if ((ret = parse_switch_page(parser, WBXML_TAG_TOKEN)) != WBXML_OK) { + return ret; + } + } + + /* Parse Tag */ + if ((ret = parse_stag(parser, &tag, &element)) != WBXML_OK ) { + return ret; + } + + WBXML_DEBUG((WBXML_PARSER, "<%s>", wbxml_tag_get_xml_name(element))); + + /* Set Current Tag */ + if (element->type == WBXML_VALUE_TOKEN) { + parser->current_tag = element->u.token; + } + + /* Parse Attributes */ + if (tag & WBXML_TOKEN_WITH_ATTRS) { + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing attributes", parser->pos)); + + /* There must be at least one attribute */ + do { + /* Parse attribute */ + if ((ret = parse_attribute(parser, &attr)) != WBXML_OK) { + wbxml_tag_destroy(element); + free_attrs_table(attrs); + return ret; + } + + /* Append this attribute in WBXMLAttribute **attrs table */ + attrs_nb++; + + if ((attrs = wbxml_realloc(attrs, + (attrs_nb + 1) * sizeof(*attrs))) == NULL) + { + /* Clean-up */ + wbxml_tag_destroy(element); + wbxml_attribute_destroy(attr); + free_attrs_table(attrs); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + attrs[(attrs_nb - 1)] = attr; + attrs[attrs_nb] = NULL; + } while ( !is_token(parser, WBXML_END) ); + + /* Skip END */ + parser->pos++; + } + + /* Is it an empty element ? */ + is_empty = (WB_BOOL) !(tag & WBXML_TOKEN_WITH_CONTENT); + + /* Callback WBXMLStartElementHandler */ + if ((parser->content_hdl != NULL) && + (parser->content_hdl->start_element_clb != NULL)) + { + parser->content_hdl->start_element_clb(parser->user_data, + element, + attrs, + is_empty); + } + + /* Free Attributes */ + free_attrs_table(attrs); + + + /* Parse *content */ + if (!is_empty) { + /* There can be NO content */ + while (!is_token(parser, WBXML_END)) { + /* Parse content */ + if ((ret = parse_content(parser, &content)) != WBXML_OK) + { + wbxml_tag_destroy(element); + return ret; + } + + /* Callback WBXMLCharactersHandler if content is not NULL */ + if ((content != NULL) && + (wbxml_buffer_len(content) != 0) && + (parser->content_hdl != NULL) && + (parser->content_hdl->characters_clb != NULL)) + { + parser->content_hdl->characters_clb(parser->user_data, + wbxml_buffer_get_cstr(content), + 0, + wbxml_buffer_len(content)); + } + + /* Free content */ + wbxml_buffer_destroy(content); + content = NULL; + } + + WBXML_DEBUG((WBXML_PARSER, "(%d) End of Element", parser->pos - 1)); + + /* Skip END */ + parser->pos++; + } + + /* Callback WBXMLEndElementHandler */ + if ((parser->content_hdl != NULL) && + (parser->content_hdl->end_element_clb != NULL)) + { + parser->content_hdl->end_element_clb(parser->user_data, + element, + is_empty); + } + + WBXML_DEBUG((WBXML_PARSER, "", wbxml_tag_get_xml_name(element))); + + /* Free Tag */ + wbxml_tag_destroy(element); + + /* Reset Current Tag */ + parser->current_tag = NULL; + + return WBXML_OK; +} + + +/** + * @brief Free a (WBXMLAttribute *) table + * @param attrs The table to ree + */ +static void free_attrs_table(WBXMLAttribute **attrs) +{ + WB_LONG i = 0; + + if (attrs != NULL) { + while (attrs[i] != NULL) { + /* Free attribute */ + wbxml_attribute_destroy(attrs[i++]); + } + wbxml_free(attrs); + } +} + + +/** + * @brief Parse WBXML switchPage + * @param parser The WBXML Parser + * @param code_space The token code space + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note switchPage = SWITCH_PAGE pageindex + */ +static WBXMLError parse_switch_page(WBXMLParser *parser, WBXMLTokenType code_space) +{ + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing switchPage", parser->pos)); + + if ((WB_UTINY) parser->version < (WB_UTINY) WBXML_VERSION_12) { + WBXML_WARNING((WBXML_PARSER, "No Switch Page mecanism possible in WBXML < %s (current: %d)", WBXML_VERSION_TEXT_12, (WB_UTINY) parser->version)); + } + + /* Skip SWITCH_PAGE token */ + parser->pos++; + + /* Change Code Page in correct Code Space */ + if (code_space == WBXML_TAG_TOKEN) + return parse_uint8(parser, &parser->tagCodePage); + else + if (code_space == WBXML_ATTR_TOKEN) + return parse_uint8(parser, &parser->attrCodePage); + else + return WBXML_ERROR_INTERNAL; +} + + +/** + * @brief Parse WBXML stag + * @param parser The WBXML Parser + * @param tag The parsed tag token + * @param element The parsed element corresponding to token + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note stag = TAG | (literalTag index) + */ +static WBXMLError parse_stag(WBXMLParser *parser, WB_UTINY *tag, WBXMLTag **element) +{ + WBXMLBuffer *name = NULL; + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing stag", parser->pos)); + + if (is_literal(parser)) { + /* Parse '(literalTag index)' */ + if ((ret = parse_literal(parser, tag, &name)) != WBXML_OK) { + return ret; + } + + /* Create Element Tag */ + if ((*element = wbxml_tag_create_literal(wbxml_buffer_get_cstr(name))) == NULL) { + ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + wbxml_buffer_destroy(name); + return ret; + } + + /* Parse 'TAG' */ + return parse_tag(parser, tag, element); +} + + +/** + * @brief Parse WBXML Application Token (tag) + * @param parser The WBXML Parser + * @param tag The parsed token tag + * @param element The parsed element (the text element corresponding to token) + * @return WBXML_OK if parsing is OK, an error code otherwise + */ +static WBXMLError parse_tag(WBXMLParser *parser, WB_UTINY *tag, WBXMLTag **element) +{ + WB_ULONG index = 0; + WB_UTINY token; + WBXMLError ret = WBXML_OK; + + /* Parse UINT8 */ + ret = parse_uint8(parser, tag); + if (ret != WBXML_OK) + return ret; + + /* Remove ATTR and CONTENT bits */ + token = (WB_UTINY) (*tag & WBXML_TOKEN_MASK); + + /* Search tag in Tags Table */ + if (parser->langTable == NULL) + return WBXML_ERROR_LANG_TABLE_UNDEFINED; + + if (parser->langTable->tagTable == NULL) + return WBXML_ERROR_TAG_TABLE_UNDEFINED; + + + while ((parser->langTable->tagTable[index].xmlName != NULL) && + ((parser->langTable->tagTable[index].wbxmlToken != token) || + (parser->langTable->tagTable[index].wbxmlCodePage != parser->tagCodePage))) { + index++; + } + + + if (parser->langTable->tagTable[index].xmlName == NULL) { +#if WBXML_PARSER_BEST_EFFORT + /* Create "unknown" Tag Element */ + if ((*element = wbxml_tag_create_literal(WBXML_PARSER_UNKNOWN_STRING)) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + return WBXML_OK; +#else + return WBXML_ERROR_UNKNOWN_TAG; +#endif /* WBXML_PARSER_BEST_EFFORT */ + } + + if ((*element = wbxml_tag_create(WBXML_VALUE_TOKEN)) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + (*element)->u.token = &(parser->langTable->tagTable[index]); + + WBXML_DEBUG((WBXML_PARSER, "(%d) Token: 0x%X", parser->pos - 1, token)); + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML attribute + * @param parser The WBXML Parser + * @param attr The resulting attribute parsed + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note attribute = attrStart *attrValue + * @warning The attr_value parameter MUST be freed by caller + */ +static WBXMLError parse_attribute(WBXMLParser *parser, WBXMLAttribute **attr) +{ + WBXMLAttributeName *attr_name = NULL; + const WB_UTINY *start_value = NULL; + WBXMLBuffer *attr_value = NULL; + WBXMLBuffer *tmp_value = NULL; + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing attribute", parser->pos)); + + /* Parse attrStart */ + if ((ret = parse_attr_start(parser, + &attr_name, + &start_value)) != WBXML_OK) + { + return ret; + } + + if ( start_value != NULL ) { + /* Create a buffer from attribute start value */ + attr_value = wbxml_buffer_create(start_value, + WBXML_STRLEN(start_value), + WBXML_PARSER_ATTR_VALUE_MALLOC_BLOCK); + } + else { + /* Create an empty buffer */ + attr_value = wbxml_buffer_create(NULL, + 0, + WBXML_PARSER_ATTR_VALUE_MALLOC_BLOCK); + } + + if (attr_value == NULL) { + /* Memory error */ + wbxml_attribute_name_destroy(attr_name); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Construct Attribute Value */ + while (is_attr_value(parser)) { + /* Parse attrValue */ + if ((ret = parse_attr_value(parser, &tmp_value)) != WBXML_OK) { + wbxml_attribute_name_destroy(attr_name); + wbxml_buffer_destroy(attr_value); + return ret; + } + + if (!wbxml_buffer_append(attr_value, tmp_value)) { + wbxml_attribute_name_destroy(attr_name); + wbxml_buffer_destroy(attr_value); + wbxml_buffer_destroy(tmp_value); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + wbxml_buffer_destroy(tmp_value); + tmp_value = NULL; + } + + if ((wbxml_buffer_len(attr_value) > 0) && + (attr_name->type == WBXML_VALUE_TOKEN)) + { + /* Handle Language Specific Attribute Values */ + switch (parser->langTable->langID) { + #if defined( WBXML_SUPPORT_SI ) + case WBXML_LANG_SI10: + /* SI 1.0: Decode date for 'created' and 'si-expires' attributes */ + if ((attr_name->u.token->wbxmlCodePage == 0x00) && + ((attr_name->u.token->wbxmlToken == 0x0a) || + (attr_name->u.token->wbxmlToken == 0x10))) + { + if ((ret = decode_datetime(attr_value)) != WBXML_OK) { + wbxml_attribute_name_destroy(attr_name); + wbxml_buffer_destroy(attr_value); + return ret; + } + } + break; + #endif /* WBXML_SUPPORT_SI */ + + #if defined( WBXML_SUPPORT_EMN ) + case WBXML_LANG_EMN10: + /* EMN 1.0: Decode date for 'timestamp' attribute */ + if ((attr_name->u.token->wbxmlCodePage == 0x00) && + (attr_name->u.token->wbxmlToken == 0x05)) + { + if ((ret = decode_datetime(attr_value)) != WBXML_OK) { + wbxml_attribute_name_destroy(attr_name); + wbxml_buffer_destroy(attr_value); + return ret; + } + } + break; + #endif /* WBXML_SUPPORT_EMN */ + + default: + break; + } + } + + /* Append NULL char to attr value */ + if (wbxml_buffer_len(attr_value) > 0) { + if (!wbxml_buffer_append_char(attr_value, '\0')) { + wbxml_attribute_name_destroy(attr_name); + wbxml_buffer_destroy(attr_value); + + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + + if ((*attr = wbxml_attribute_create()) == NULL) { + wbxml_attribute_name_destroy(attr_name); + wbxml_buffer_destroy(attr_value); + + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + (*attr)->name = attr_name; + (*attr)->value = attr_value; + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML content + * @param parser The WBXML Parser + * @param result Resulting parsed content, if content is not an Element + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note content = element | string | extension | entity | pi | opaque + */ +static WBXMLError parse_content(WBXMLParser *parser, WBXMLBuffer **result) +{ + WB_UTINY cur_byte; + WBXMLError ret = WBXML_OK; + + /* Debug */ + if (!wbxml_buffer_get_char(parser->wbxml, parser->pos, &cur_byte)) + return WBXML_ERROR_END_OF_BUFFER; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing content: '0x%X'", parser->pos, cur_byte)); + + /* extension */ + if (is_extension(parser)) + return parse_extension(parser, WBXML_TAG_TOKEN, result); + + /* entity */ + if (is_token(parser, WBXML_ENTITY)) + return parse_entity(parser, result); + + /* string */ + if (is_string(parser)) + return parse_string(parser, result); + + /* opaque */ + if (is_token(parser, WBXML_OPAQUE)) { + if ((ret = parse_opaque(parser, result)) != WBXML_OK) + return ret; + + return decode_opaque_content(parser, result); + } + + /* pi */ + if (is_token(parser, WBXML_PI)) + return parse_pi(parser); + + /** + * @note Non standard behaviour because of a Nokia 6600 bug + * that generate switch pages in wrong places. + * + * Thanks to Balaji Alasyam for finding this bug. + * + * Example : 02 9F 53 6A 00 6D 6C 71 C3 03 31 2E 31 01 72 C3 0A 53 79 6E + * 63 4D 4C 2F 31 2E 31 01 65 C3 01 34 01 5B C3 01 31 01 6E 57 + * C3 31 68 74 74 70 3A 2F 2F 32 31 30 2E 32 31 34 2E 31 36 31 + * 2E 31 37 32 3A 38 30 38 30 2F 74 65 73 74 2F 53 79 6E 63 4D + * 4C 3F 75 73 65 72 3D 62 61 6C 75 01 01 67 57 C3 14 49 4D 45 + * 49 3A 33 35 31 35 34 36 30 30 35 33 39 34 31 39 39 01 01 5A + * 00 01 4C C3 05 31 30 30 30 30 01 00 00 01 01 6B 46 4B C3 ... + * ^^^^^ + */ + + /* switchPage */ + if ( is_token(parser, WBXML_SWITCH_PAGE) ) + return parse_switch_page(parser, WBXML_TAG_TOKEN); + + /** @note We have recurrency here ! */ + return parse_element(parser); +} + + +/** + * @brief Parse WBXML string + * @param parser [in] The WBXML Parsertatic + * @param result [out] The resulting parsed string + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note string = inline | tableref + */ +static WBXMLError parse_string(WBXMLParser *parser, WBXMLBuffer **result) +{ + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing string", parser->pos)); + + if (is_token(parser, WBXML_STR_I)) + return parse_inline(parser, result); + + if (is_token(parser, WBXML_STR_T)) + return parse_tableref(parser, result); + + return WBXML_ERROR_STRING_EXPECTED; +} + + +/** + * @brief Parse WBXML extension + * @param parser The WBXML Parser + * @param code_space The token code space + * @param result Resulting parsed extension + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note extension = [switchPage] (( EXT_I termstr ) | ( EXT_T index ) | EXT) + * @note 5.8.4.2 - The effect of a switchPage preceding an extension will depend upon where the extension appears. + * If switchPage appears in content, it will change the tag code page. Is switchPage appears in + * an attribute list, it will change the attribute code page. + * @note Extensions tokens are explained in WML Specifications (WAP-191-WML-20000219-a.pdf - 14.1.1 & 14.3) + * @warning The resulting ext paramater MUST be freed by caller ! + */ +static WBXMLError parse_extension(WBXMLParser *parser, WBXMLTokenType code_space, WBXMLBuffer **result) +{ + WB_UTINY *ext = NULL; + WB_ULONG len = 0; + WBXMLError ret = WBXML_OK; + WB_UTINY token = 0; + +#if ( defined ( WBXML_SUPPORT_WML ) || defined ( WBXML_SUPPORT_WTA ) ) + WB_UTINY var_begin[3] = "$(", + var_end[2] = ")", + escape[8] = ":escape", + unesc[7] = ":unesc", + noesc[7] = ":noesc"; + + WBXMLBuffer *var_value = NULL; + WB_ULONG index = 0; +#endif /* WBXML_SUPPORT_WML || WBXML_SUPPORT_WTA */ + +#if defined ( WBXML_SUPPORT_WV ) + WB_ULONG ext_value = 0; + WB_UTINY tab_index = 0; +#endif /* WBXML_SUPPORT_WV */ + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing extension", parser->pos)); + + /* Parse switchPage */ + if (is_token(parser, WBXML_SWITCH_PAGE)) { + if ((ret = parse_switch_page(parser, code_space)) != WBXML_OK) { + return ret; + } + } + + /* Get Extension Token */ + if ((ret = parse_uint8(parser, &token)) != WBXML_OK) { + return ret; + } + + + /* Language specific treatment */ + switch (parser->langTable->langID) { + +#if defined( WBXML_SUPPORT_WML ) + + case WBXML_LANG_WML10: + case WBXML_LANG_WML11: + case WBXML_LANG_WML12: + case WBXML_LANG_WML13: + +#endif /* WBXML_SUPPORT_WML */ + +#if defined( WBXML_SUPPORT_WTA ) + + case WBXML_LANG_WTAWML12: + +#endif /* WBXML_SUPPORT_WTA */ + +#if ( defined( WBXML_SUPPORT_WML ) || defined( WBXML_SUPPORT_WTA ) ) + + /***************************** + * WML Variable Substitution + */ + + switch (token) { + case WBXML_EXT_0: + case WBXML_EXT_1: + case WBXML_EXT_2: + WBXML_WARNING((WBXML_PARSER, "This extension token is reserved for futur use (ignoring)")); + return WBXML_OK; + + case WBXML_EXT_I_0: + case WBXML_EXT_I_1: + case WBXML_EXT_I_2: + /* Inline variable */ + if ((ret = parse_termstr(parser, &var_value)) != WBXML_OK) { + WBXML_ERROR((WBXML_PARSER, "Bad Inline Extension")); + return ret; + } + break; + + case WBXML_EXT_T_0: + case WBXML_EXT_T_1: + case WBXML_EXT_T_2: + /* Index in String Table */ + if ((ret = parse_mb_uint32(parser, &index)) != WBXML_OK) { + return ret; + } + + if ((ret = get_strtbl_reference(parser, + index, + &var_value)) != WBXML_OK) + { + WBXML_ERROR((WBXML_PARSER, "Bad Extension reference in string table")); + return ret; + } + break; + + default: + return WBXML_ERROR_UNKNOWN_EXTENSION_TOKEN; + } + + /* Build Variable */ + ext = (WB_UTINY*) wbxml_malloc(WBXML_STRLEN(var_begin) + + wbxml_buffer_len(var_value) + + WBXML_STRLEN(escape) + + WBXML_STRLEN(var_end) + 1); + if (ext == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Generate "$(" */ + memcpy(ext + len, var_begin, WBXML_STRLEN(var_begin)); + len += WBXML_STRLEN(var_begin); + + /* Generate 'variable' */ + memcpy(ext + len, wbxml_buffer_get_cstr(var_value), wbxml_buffer_len(var_value)); + len += wbxml_buffer_len(var_value); + + /* Destroy 'variable' */ + wbxml_buffer_destroy(var_value); + + switch (token) { + case WBXML_EXT_I_0: + case WBXML_EXT_T_0: + /* Generate ":escape" */ + memcpy(ext + len, escape, WBXML_STRLEN(escape)); + len += WBXML_STRLEN(escape); + break; + + case WBXML_EXT_I_1: + case WBXML_EXT_T_1: + /* Generate ":unesc" */ + memcpy(ext + len, unesc, WBXML_STRLEN(unesc)); + len += WBXML_STRLEN(unesc); + break; + + case WBXML_EXT_I_2: + case WBXML_EXT_T_2: + /* Generate ":noesc" */ + memcpy(ext + len, noesc, WBXML_STRLEN(noesc)); + len += WBXML_STRLEN(noesc); + break; + + default: + return WBXML_ERROR_UNKNOWN_EXTENSION_TOKEN; + } + + /* Generate ")" */ + memcpy(ext + len, var_end, WBXML_STRLEN(var_end)); + len += WBXML_STRLEN(var_end); + + break; + +#endif /* WBXML_SUPPORT_WML || WBXML_SUPPORT_WTA */ + +#if defined( WBXML_SUPPORT_WV ) + + case WBXML_LANG_WV_CSP11: + case WBXML_LANG_WV_CSP12: + + /********************************** + * Wireless Village extension + */ + + if (token != WBXML_EXT_T_0) { + WBXML_ERROR((WBXML_PARSER, "Only EXT_T_0 extensions authorized with Wireless Village CSP")); + return WBXML_OK; + } + + /* Get Extension Value Token */ + if ((ret = parse_mb_uint32(parser, &ext_value)) != WBXML_OK) { + return ret; + } + + /* Search Token in Extension Value Table */ + if (parser->langTable == NULL) { + return WBXML_ERROR_LANG_TABLE_UNDEFINED; + } + + if (parser->langTable->extValueTable == NULL) { + return WBXML_ERROR_EXT_VALUE_TABLE_UNDEFINED; + } + + tab_index = 0; + + while ((parser->langTable->extValueTable[tab_index].xmlName != NULL) && + (parser->langTable->extValueTable[tab_index].wbxmlToken != ext_value) ) + { + tab_index++; + } + + if (parser->langTable->extValueTable[tab_index].xmlName == NULL) { +#if WBXML_PARSER_BEST_EFFORT + ext = (WB_UTINY *) wbxml_strdup((const WB_TINY*) WBXML_PARSER_UNKNOWN_STRING); + len = WBXML_STRLEN(WBXML_PARSER_UNKNOWN_STRING); + return WBXML_OK; +#else + return WBXML_ERROR_UNKNOWN_EXTENSION_VALUE; +#endif /* WBXML_PARSER_BEST_EFFORT */ + } + + ext = (WB_UTINY *) wbxml_strdup((const WB_TINY*) parser->langTable->extValueTable[tab_index].xmlName); + len = WBXML_STRLEN(parser->langTable->extValueTable[tab_index].xmlName); + break; + +#endif /* WBXML_SUPPORT_WV */ + + default: + WBXML_ERROR((WBXML_PARSER, "Extension tokens not allowed with this Document !")); + } + + /* Set result */ + if (ext == NULL) { + *result = NULL; + } + else { + if ((*result = wbxml_buffer_create(ext, len, len)) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /** @todo Replace this local var by the direct creation of the result Buffer */ + wbxml_free(ext); + } + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML entity + * @param parser The WBXML Parser + * @param result The resulting parsed entity + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note entity = ENTITY entcode + * @note http://www.w3.org/TR/wbxml/ : + * "The character entity token (ENTITY) encodes a numeric character entity. This has the same semantics + * as an XML numeric character entity (eg, ). The mb_u_int32 refers to a character in the UCS-4 + * character encoding. All entities in the source XML document must be represented using either a string + * token (eg, STR_I or the ENTITY token." + * @warning The resulting entity paramater MUST be freed by caller ! + */ +static WBXMLError parse_entity(WBXMLParser *parser, WBXMLBuffer **result) +{ + WB_ULONG code = 0; + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing entity", parser->pos)); + + /* Skip ENTITY */ + parser->pos++; + + if ( (ret = parse_entcode(parser, &code)) != WBXML_OK ) { + return ret; + } + + /* + * Convert the UCS-4 code to a UTF-8 encoded string. + */ + + assert(code < 0x80000000); + + if (code < 0x80) + { + /* For codes under 0x80, we don't need any fancy formatting. */ + WB_TINY entity[2] = {(WB_TINY)code, 0}; + + /* Create result buffer */ + if ( (*result = wbxml_buffer_create_from_cstr(entity)) == NULL ) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + return WBXML_OK; + } + else + { + WB_UTINY masks[5] = {0xFC, 0xF8, 0xF0, 0xE0, 0xC0}; + WB_UTINY entity[7] = {0, 0, 0, 0, 0, 0, 0}; + + int index = 5; + while (code >= 0x40) + { + entity[index] = 0x80 | (code & 0x3F); + code >>= 6; index--; + } + entity[index] = masks[index] | code; + + /* Create result buffer */ + if ( (*result = wbxml_buffer_create_from_cstr((WB_TINY *) entity + index)) == NULL ) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + return WBXML_OK; + } +} + + +/** + * @brief Parse WBXML opaque + * @param parser The WBXML Parser + * @param result Resulting opaque data parsed + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note opaque = OPAQUE length *byte + * @note length = mb_u_int32 + */ +static WBXMLError parse_opaque(WBXMLParser *parser, WBXMLBuffer **result) +{ + WB_ULONG len = 0; + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing opaque", parser->pos)); + + if (parser->version < WBXML_VERSION_11) { + WBXML_WARNING((WBXML_PARSER, "No 'opaque' support in WBXML < %s", WBXML_VERSION_TEXT_11)); + } + + /* Skip OPAQUE */ + parser->pos++; + + if ((ret = parse_mb_uint32(parser, &len)) != WBXML_OK) { + return ret; + } + + /* Check that length specified in OPAQUE doesn't overflow wbxml length */ + if (len > wbxml_buffer_len(parser->wbxml) - parser->pos) { + return WBXML_ERROR_BAD_OPAQUE_LENGTH; + } + + /** + * Create result buffer (don't create a static buffer, because this can be + * modified while trying to decode this content) + */ + *result = wbxml_buffer_create(wbxml_buffer_get_cstr(parser->wbxml) + parser->pos, len, len); + if (*result == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + parser->pos += len; + + return ret; +} + + +/** + * @brief Parse WBXML literalTag + * @param parser The WBXML Parser + * @param mask Resulting tag mask (WBXML_TOKEN_MASK | + * WBXML_TOKEN_WITH_CONTENT | + * WBXML_TOKEN_WITH_ATTRS | + * (WBXML_TOKEN_WITH_CONTENT || WBXML_TOKEN_WITH_ATTRS)) + * @param result The resulting parsed literal + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note result = ( literalTag index ) + * literalTag = LITERAL | LITERAL_A | LITERAL_C | LITERAL_AC + */ +static WBXMLError parse_literal(WBXMLParser *parser, + WB_UTINY *mask, + WBXMLBuffer **result) +{ + WBXMLError ret = WBXML_OK; + WB_UTINY token = 0; + WB_ULONG index = 0; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing literalTag", parser->pos)); + + /* Parse literalTag */ + if ( (ret = parse_uint8(parser, &token)) != WBXML_OK ) { + return ret; + } + + /* Parse index */ + if ( (ret = parse_mb_uint32(parser, &index)) != WBXML_OK ) { + return ret; + } + + /* Get string */ + if ( (ret = get_strtbl_reference(parser, index, result)) != WBXML_OK ) { + return ret; + } + + /* Build Tag Mask */ + switch(token) { + case WBXML_LITERAL: + *mask = WBXML_TOKEN_MASK; + break; + + case WBXML_LITERAL_C: + *mask = WBXML_TOKEN_WITH_CONTENT; + break; + + case WBXML_LITERAL_A: + *mask = WBXML_TOKEN_WITH_ATTRS; + break; + + case WBXML_LITERAL_AC: + *mask = ( WBXML_TOKEN_WITH_CONTENT | WBXML_TOKEN_WITH_ATTRS ); + break; + + default: + return WBXML_ERROR_INTERNAL; + } + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML attrStart + * @param parser The WBXML Parser + * @param name The Attribute Name parsed + * @param value The Attribute Value associated, if any + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note attrStart = ([switchPage] ATTRSTART) | ( LITERAL index ) + */ +static WBXMLError parse_attr_start(WBXMLParser *parser, + WBXMLAttributeName **name, + const WB_UTINY **value) +{ + WBXMLBuffer *literal_str = NULL; + WB_UTINY literal = 0; + WB_UTINY tag = 0; + WBXMLError ret = WBXML_OK; + WB_ULONG index = 0; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing attrStart", parser->pos)); + + + /************************** + * Case: ( LITERAL index ) + */ + + if (is_token(parser, WBXML_LITERAL)) { + if ((ret = parse_literal(parser, &literal, &literal_str)) != WBXML_OK) { + return ret; + } + + if ((*name = wbxml_attribute_name_create_literal(wbxml_buffer_get_cstr(literal_str))) == NULL) { + ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /** + * @todo Return Warning if 'literal' is different from 'WBML_TOKEN_MASK' (because it MUST be a 'LITERAL' token, not + * LITERAL_A, nor LITERAL_C, nor LITERAL_AC + */ + + wbxml_buffer_destroy(literal_str); + return WBXML_OK; + } + + + /*********************************** + * Case: ( [switchPage] ATTRSTART ) + */ + + /* Parse switchPage */ + if (is_token(parser, WBXML_SWITCH_PAGE)) { + if ((ret = parse_switch_page(parser, WBXML_ATTR_TOKEN)) != WBXML_OK) { + return ret; + } + } + + /* Parse UINT8 */ + if ((ret = parse_uint8(parser, &tag)) != WBXML_OK) { + return ret; + } + + WBXML_DEBUG((WBXML_PARSER, "\tToken: 0x%X", tag)); + + /* Search tag in Tags Table */ + if (parser->langTable == NULL) { + return WBXML_ERROR_LANG_TABLE_UNDEFINED; + } + + if (parser->langTable->attrTable == NULL) { + return WBXML_ERROR_ATTR_TABLE_UNDEFINED; + } + + while ((parser->langTable->attrTable[index].xmlName != NULL) && + ((parser->langTable->attrTable[index].wbxmlToken != tag) || + (parser->langTable->attrTable[index].wbxmlCodePage != parser->attrCodePage))) + { + index++; + } + + if (parser->langTable->attrTable[index].xmlName == NULL) { +#if WBXML_PARSER_BEST_EFFORT + /* Create "unknown" Attribute Name */ + if ((*name = wbxml_attribute_name_create_literal(WBXML_PARSER_UNKNOWN_STRING)) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + return WBXML_OK; +#else + return WBXML_ERROR_UNKNOWN_ATTR; +#endif /* WBXML_PARSER_BEST_EFFORT */ + } + + /* Create Token Attribute Name */ + if ((*name = wbxml_attribute_name_create(WBXML_VALUE_TOKEN)) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + (*name)->u.token = &(parser->langTable->attrTable[index]); + + /* Get Attribute start value (if any) */ + if (parser->langTable->attrTable[index].xmlValue != NULL) { + *value = (const WB_UTINY *) parser->langTable->attrTable[index].xmlValue; + } + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML attrValue + * @param parser [in] The WBXML Parser + * @param result [out] The resulting Value parsed + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note attrValue = ([switchPage] ATTRVALUE) | string | extension | entity | opaque + */ +static WBXMLError parse_attr_value(WBXMLParser *parser, + WBXMLBuffer **result) +{ + WB_ULONG index = 0; + WB_UTINY tag = 0; + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing attrValue", parser->pos)); + + /* Parse extension */ + if (is_extension(parser)) { + return parse_extension(parser, WBXML_ATTR_TOKEN, result); + } + + /* Parse entity */ + if (is_token(parser, WBXML_ENTITY)) { + return parse_entity(parser, result); + } + + /* Parse string */ + if (is_string(parser)) { + return parse_string(parser, result); + } + + /* Parse opaque */ + if (is_token(parser, WBXML_OPAQUE)) { + if (parser->version < WBXML_VERSION_12) { + WBXML_ERROR((WBXML_PARSER, "An Attribute value can't be 'opaque' in WBXML version < %s", WBXML_VERSION_TEXT_12)); + } + + if ((ret = parse_opaque(parser, result)) != WBXML_OK) + return ret; + + return decode_opaque_attr_value(parser, result); + } + + + /***************************** + * ([switchPage] ATTRVALUE) + */ + + /* Parse switchPage */ + if (is_token(parser, WBXML_SWITCH_PAGE)) { + ret = parse_switch_page(parser, WBXML_ATTR_TOKEN); + if (ret != WBXML_OK) { + return ret; + } + } + + /* Parse UINT8 */ + ret = parse_uint8(parser, &tag); + if (ret != WBXML_OK) { + return ret; + } + + /* Search tag in Tags Table */ + if (parser->langTable == NULL) { + return WBXML_ERROR_LANG_TABLE_UNDEFINED; + } + + if (parser->langTable->attrValueTable == NULL) { + return WBXML_ERROR_ATTR_VALUE_TABLE_UNDEFINED; + } + + while ((parser->langTable->attrValueTable[index].xmlName != NULL) && + ((parser->langTable->attrValueTable[index].wbxmlToken != tag) || + (parser->langTable->attrValueTable[index].wbxmlCodePage != parser->attrCodePage))) + { + index++; + } + + if (parser->langTable->attrValueTable[index].xmlName == NULL) { + return WBXML_ERROR_UNKNOWN_ATTR_VALUE; + } + + *result = wbxml_buffer_sta_create_from_cstr(parser->langTable->attrValueTable[index].xmlName); + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML termstr + * @param parser [in] The WBXML Parser + * @param result [out] The resulting parsed string + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note termstr = charset-dependent string with termination + */ +static WBXMLError parse_termstr(WBXMLParser *parser, + WBXMLBuffer **result) +{ + WB_ULONG max_len = 0; + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing termstr", parser->pos)); + + /* Get max possible string length */ + max_len = wbxml_buffer_len(parser->wbxml) - parser->pos; + + /* Convert to UTF-8 Buffer */ + if ((ret = wbxml_charset_conv_term((const WB_TINY *) (wbxml_buffer_get_cstr(parser->wbxml) + parser->pos), + &max_len, + parser->charset, + result, + WBXML_CHARSET_UTF_8)) != WBXML_OK) { + return ret; + } + + parser->pos += max_len; + + WBXML_DEBUG((WBXML_PARSER, "(%d) termstr: %s", parser->pos, wbxml_buffer_get_cstr(*result))); + + return WBXML_OK; +} + + +/** + * @brief Parse WBXML inline + * @param parser [in] The WBXML Parser + * @param result [out] The resulting parsed string + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note inline = STR_I termstr + */ +static WBXMLError parse_inline(WBXMLParser *parser, + WBXMLBuffer **result) +{ + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing inline", parser->pos)); + + /* Skip STR_I */ + parser->pos++; + + return parse_termstr(parser, result); +} + + +/** + * @brief Parse WBXML tableref + * @param parser The WBXML Parser + * @param result The resulting parsed string + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note tableref = STR_T index + * @note index = mb_u_int32 + */ +static WBXMLError parse_tableref(WBXMLParser *parser, + WBXMLBuffer **result) +{ + WB_ULONG index; + WBXMLError ret = WBXML_OK; + + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing tableref", parser->pos)); + + /* Skip STR_T */ + parser->pos++; + + /* Parse index */ + if ((ret = parse_mb_uint32(parser, &index)) != WBXML_OK) { + return ret; + } + + return get_strtbl_reference(parser, index, result); +} + + +/** + * @brief Parse WBXML entcode + * @param parser [in] The WBXML Parser + * @param result [out] The entcode parsed + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note entcode = mb_u_int32 // UCS-4 character code + */ +static WBXMLError parse_entcode(WBXMLParser *parser, + WB_ULONG *result) +{ + WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing entcode", parser->pos)); + + return parse_mb_uint32(parser, result); +} + + +/** + * @brief Get a string from String Table + * @param parser The WBXML Parser + * @param index Index of string in String Table + * @param result The resulting parsed string + * @return WBXML_OK if OK, an error code otherwise + */ +static WBXMLError get_strtbl_reference(WBXMLParser *parser, + WB_ULONG index, + WBXMLBuffer **result) +{ + WB_ULONG max_len = 0; + WBXMLError ret = WBXML_OK; + + /* WORKAROUND: 2011-Jan-21 Michael Bell + * WORKAROUND: + * WORKAROUND: Nokia encodes the name space not only in the publicid. + * WORKAROUND: Some Nokia software encodes the SyncML name space + * WORKAROUND: as an attribute without a name and without a string + * WORKAROUND: table but with a LITAERAL and an index. + * WORKAROUND: + * WORKAROUND: Example: ED 04 00 03 SYNCML:SYNCML1.2 00 + * WORKAROUND: ED => 2D => SyncML + * WORKAROUND: 04 => LITERAL (incl. ATTRSTART) + * WORKAROUND: 00 => index 0 (without string table) + * WORKAROUND: 03 => TOKEN_STR_I (inline sring) + * WORKAROUND: + * WORKAROUND: If this mistake is detected then "xmlns" is returned. + */ + if (parser->strstbl == NULL && index == 0) { + WBXML_DEBUG((WBXML_PARSER, "(%d) Workaround Nokia: NO string table, index 0 => encoded xmlns", parser->pos)); + + /* UTF-8 xmlns */ + if ((*result = wbxml_buffer_create_from_cstr("xmlns")) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + return WBXML_OK; + } + + /* Check if strtbl is NULL */ + if (parser->strstbl == NULL) { + return WBXML_ERROR_NULL_STRING_TABLE; + } + + if (index >= wbxml_buffer_len(parser->strstbl)) { + return WBXML_ERROR_INVALID_STRTBL_INDEX; + } + + /* Get max possible string length */ + max_len = wbxml_buffer_len(parser->strstbl) - index; + + /* Convert to UTF-8 Buffer */ + if ((ret = wbxml_charset_conv_term((const WB_TINY *) (wbxml_buffer_get_cstr(parser->strstbl) + index), + &max_len, + parser->charset, + result, + WBXML_CHARSET_UTF_8)) != WBXML_OK) { + return ret; + } + + WBXML_DEBUG((WBXML_PARSER, "(%d) String Table Reference: %s", parser->pos, wbxml_buffer_get_cstr(*result))); + + return WBXML_OK; +} + + +/******************************** + * Basic Types Parse functions + */ + +/** + * @brief Parse UINT8 + * @param parser [in] The WBXML Parser + * @param result [out] Parsed UINT8 + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note u_int8 = 8 bit unsigned integer + */ +static WBXMLError parse_uint8(WBXMLParser *parser, WB_UTINY *result) +{ + if (parser == NULL) + return WBXML_ERROR_NULL_PARSER; + + if (result == NULL) + return WBXML_ERROR_BAD_PARAMETER; + + if (parser->pos == wbxml_buffer_len(parser->wbxml)) + return WBXML_ERROR_END_OF_BUFFER; + + if (!wbxml_buffer_get_char(parser->wbxml, parser->pos, result)) + return WBXML_ERROR_END_OF_BUFFER; + + parser->pos++; + + return WBXML_OK; +} + + +/** + * @brief Parse a MultiByte UINT32 + * @param parser The WBXML Parser + * @param result The parsed MultiByte + * @return WBXML_OK if parsing is OK, an error code otherwise + * @note mb_u_int32 = 32 bit unsigned integer, encoded in multi-byte format + */ +static WBXMLError parse_mb_uint32(WBXMLParser *parser, WB_ULONG *result) +{ + WB_ULONG uint = 0, byte_pos; + WB_UTINY cur_byte; + + if (parser == NULL) + return WBXML_ERROR_NULL_PARSER; + + if (result == NULL) + return WBXML_ERROR_BAD_PARAMETER; + + /* It's a 32bit integer, and so it fits to a maximum of 4 bytes */ + for (byte_pos = 0; byte_pos < 5; byte_pos++) { + /* Get current byte */ + if (!wbxml_buffer_get_char(parser->wbxml, parser->pos, &cur_byte)) + return WBXML_ERROR_END_OF_BUFFER; + + /* Move to next byte */ + parser->pos++; + + /* Update uint value */ + uint = (uint << 7) | ((WB_UTINY)cur_byte & 0x7F); + + /* Check first bit, and stop if value is zero */ + if (!((WB_UTINY)cur_byte & 0x80)) { + *result = uint; + return WBXML_OK; + } + } + + return WBXML_ERROR_UNVALID_MBUINT32; +} + + +/**************************************** + * Language Specific Decoding Functions + */ + +/** + * @brief Decode a BASE64 value + * @param data [in/out]The value to decode + * @return WBXML_OK if OK, another error code otherwise + */ +static WBXMLError decode_base64_value(WBXMLBuffer **data) +{ + WB_UTINY *result = NULL; + WBXMLError ret = WBXML_OK; + + if ((data == NULL) || (*data == NULL)) { + return WBXML_ERROR_INTERNAL; + } + + if ((result = wbxml_base64_encode((const WB_UTINY *) wbxml_buffer_get_cstr(*data), + wbxml_buffer_len(*data))) == NULL) + { + return WBXML_ERROR_B64_ENC; + } + + /* Reset buffer */ + wbxml_buffer_delete(*data, 0, wbxml_buffer_len(*data)); + + /* Set data */ + if (!wbxml_buffer_append_cstr(*data, result)) { + ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + wbxml_free(result); + + return ret; +} + + +#if ( defined( WBXML_SUPPORT_SI ) || defined( WBXML_SUPPORT_EMN ) ) + +/************************************** + * SI 1.0 / EMN 1.0 + */ + +/** + * @brief Decode a %Datetime Attribute Value + * @param buff The Attribute Value to convert + * @return WBXML_OK if OK, another error code otherwise + * @note Used for: + * - SI 1.0: Decode date for 'created' and 'si-expires' attributes + * - EMN 1.0: Decode date for 'timestamp' attribute + */ +static WBXMLError decode_datetime(WBXMLBuffer *buff) +{ + WB_ULONG len = 0; + + /* Binary to Hexa */ + if (!wbxml_buffer_binary_to_hex(buff, TRUE)) + return WBXML_ERROR_INTERNAL; + + /* Check Integrity */ + len = wbxml_buffer_len(buff); + if ((len < 8) || (len > 14) || (len == 9) || (len == 11) || (len == 13)) + return WBXML_ERROR_BAD_DATETIME; + + /* Date */ + + /* "1999-" */ + if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *)"-", 4)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* "1999-04-" */ + if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *)"-", 7)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* "1999-04-30T" */ + if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *)"T", 10)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Time */ + + /* Append ':' delimiters */ + if (len > 10) { + if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *)":", 13)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + if (len > 12) { + if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *)":", 16)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Append Trailing Zeros */ + switch (len) { + case 8: + if (!wbxml_buffer_append_cstr(buff, (WB_UTINY *)"00:00:00")) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + break; + case 10: + if (!wbxml_buffer_append_cstr(buff, (WB_UTINY *)":00:00")) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + break; + case 12: + if (!wbxml_buffer_append_cstr(buff, (WB_UTINY *)":00")) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + break; + default: + /* 14 : Nothing to do */ + break; + } + + /* Append ending 'Z' character */ + if (!wbxml_buffer_append_char(buff, 'Z')) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + return WBXML_OK; +} + +#endif /* WBXML_SUPPORT_SI || WBXML_SUPPORT_EMN */ + + +/** + * @brief Decode an Opaque Content buffer + * @param parser The WBXML Parser + * @param data The Opaque data buffer + * @return WBXML_OK if OK, another error code otherwise + */ +static WBXMLError decode_opaque_content(WBXMLParser *parser, + WBXMLBuffer **data) +{ + switch (parser->langTable->langID) + { + +#if defined( WBXML_SUPPORT_WV ) + + case WBXML_LANG_WV_CSP11: + case WBXML_LANG_WV_CSP12: + return decode_wv_content(parser, data); + break; + +#endif /* WBXML_SUPPORT_WV */ + +#if defined( WBXML_SUPPORT_DRMREL ) + + case WBXML_LANG_DRMREL10: + /* ds:KeyValue */ + if ((parser->current_tag->wbxmlCodePage == 0x00) && + (parser->current_tag->wbxmlToken == 0x0C)) + { + WBXMLError ret = WBXML_OK; + + /* Decode base64 value */ + if ((ret = decode_base64_value(data)) != WBXML_OK) + return ret; + + return WBXML_OK; + } + break; + +#endif /* WBXML_SUPPORT_DRMREL */ + +#if defined( WBXML_SUPPORT_SYNCML ) + + case WBXML_LANG_SYNCML_SYNCML10: + case WBXML_LANG_SYNCML_SYNCML11: + case WBXML_LANG_SYNCML_SYNCML12: + /* NextNonce */ + if ((parser->current_tag->wbxmlCodePage == 0x01) && + (parser->current_tag->wbxmlToken == 0x10)) + { + WBXMLError ret = WBXML_OK; + + /* Decode base64 value */ + if ((ret = decode_base64_value(data)) != WBXML_OK) + return ret; + + return WBXML_OK; + } + break; + +#endif /* WBXML_SUPPORT_SYNCML */ + + default: + /* NOP */ + break; + } /* switch */ + + return WBXML_OK; +} + + +/** + * @brief Decode an Opaque Attribute Value buffer + * @param parser The WBXML Parser + * @param data The Opaque data buffer + * @return WBXML_OK if OK, another error code otherwise + */ +static WBXMLError decode_opaque_attr_value(WBXMLParser *parser, WBXMLBuffer **data) +{ + switch (parser->langTable->langID) + { +#if defined( WBXML_SUPPORT_OTA_SETTINGS ) + + case WBXML_LANG_OTA_SETTINGS: + { + WBXMLError ret = WBXML_OK; + + /* Decode base64 value */ + if ((ret = decode_base64_value(data)) != WBXML_OK) + return ret; + + return WBXML_OK; + } + +#endif /* WBXML_SUPPORT_OTA_SETTINGS */ + + default: + /* NOP */ + break; + } /* switch */ + + return WBXML_OK; +} + + +#if defined( WBXML_SUPPORT_WV ) + +/************************************** + * WV 1.1 / WV 1.2 + */ + +/** + * @brief Decode a WV Content encoded in an Opaque + * @param parser The WBXML Parser + * @param data The WV Integer to decode + * @return WBXML_OK if OK, another error code otherwise + * @note Used for: + * - WV 1.1 / 1.2 + */ +static WBXMLError decode_wv_content(WBXMLParser *parser, WBXMLBuffer **data) +{ + WBXMLWVDataType data_type = WBXML_WV_DATA_TYPE_STRING; + WBXMLError ret = WBXML_OK; + + /* Wireless-Village 1.1 / 1.2 */ + + /* + * Specific WV Opaque Data Type Elements: + * + * Integer: + * Code (0x00 / 0x0B) + * ContentSize (0x00 / 0x0F) + * MessageCount (0x00 / 0x1A) + * Validity (0x00 / 0x3C) + * KeepAliveTime (0x01 / 0x1C) + * SearchFindings (0x01 / 0x25) + * SearchID (0x01 / 0x26) + * SearchIndex (0x01 / 0x27) + * SearchLimit (0x01 / 0x28) + * TimeToLive (0x01 / 0x32) + * AcceptedCharSet (0x03 / 0x05) + * AcceptedContentLength (0x03 / 0x06) + * MultiTrans (0x03 / 0x0C) + * ParserSize (0x03 / 0x0D) + * ServerPollMin (0x03 / 0x0E) + * TCPPort (0x03 / 0x12) + * UDPPort (0x03 / 0x13) + * HistoryPeriod (0x09 / 0x08) [WV 1.2] + * MaxWatcherList (0x09 / 0x0A) [WV 1.2] + * + * Date and Time: + * DateTime (0x00 / 0x11) + * DeliveryTime (0x06 / 0x1A) + * + * Binary: + * ContentData (0x00 / 0x0D) (only if we have a: + * "BASE64" associated) + */ + + /*********************************************** + * Check the Data Type, given the Current Tag + */ + + switch (parser->current_tag->wbxmlCodePage) { + case 0x00: + /* Code Page: 0x00 */ + switch (parser->current_tag->wbxmlToken) { + case 0x0B: /* Code */ + case 0x0F: /* ContentSize */ + case 0x1A: /* MessageCount */ + case 0x3C: /* Validity */ + /* INTEGER */ + data_type = WBXML_WV_DATA_TYPE_INTEGER; + break; + + case 0x11: /* DateTime */ + /* DATE_AND_TIME */ + data_type = WBXML_WV_DATA_TYPE_DATE_AND_TIME; + break; + + case 0x0D: /* ContentData */ + /* BINARY */ + /** @todo Check if we have a: "BASE64" associated */ + /* + if (base64_encoded) + data_type = WBXML_WV_DATA_TYPE_BINARY; + else + */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + + case 0x01: + /* Code Page: 0x01 */ + switch (parser->current_tag->wbxmlToken) { + case 0x1C: /* KeepAliveTime */ + case 0x25: /* SearchFindings */ + case 0x26: /* SearchID */ + case 0x27: /* SearchIndex */ + case 0x28: /* SearchLimit */ + case 0x32: /* TimeToLive */ + /* INTEGER */ + data_type = WBXML_WV_DATA_TYPE_INTEGER; + break; + + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + + case 0x03: + /* Code Page: 0x03 */ + switch (parser->current_tag->wbxmlToken) { + case 0x05: /* AcceptedCharSet */ + case 0x06: /* AcceptedContentLength */ + case 0x0C: /* MultiTrans */ + case 0x0D: /* ParserSize */ + case 0x0E: /* ServerPollMin */ + case 0x12: /* TCPPort */ + case 0x13: /* UDPPort */ + /* INTEGER */ + data_type = WBXML_WV_DATA_TYPE_INTEGER; + break; + + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + + case 0x05: + /* Code Page: 0x05 */ + switch (parser->current_tag->wbxmlToken) { + case 0x05: /* Altitude */ + case 0x09: /* Accuracy */ + case 0x32: /* Cpriority */ + /* INTEGER */ + data_type = WBXML_WV_DATA_TYPE_INTEGER; + break; + + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + + case 0x06: + /* Code Page: 0x06 */ + switch (parser->current_tag->wbxmlToken) { + case 0x1A: /* DeliveryTime */ + /* DATE AND TIME */ + data_type = WBXML_WV_DATA_TYPE_DATE_AND_TIME; + break; + + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + + case 0x09: + /* Code Page: 0x09 */ + switch (parser->current_tag->wbxmlToken) { + case 0x08: /* HistoryPeriod */ + case 0x0A: /* MaxWatcherList */ + /* INTEGER */ + data_type = WBXML_WV_DATA_TYPE_INTEGER; + break; + + default: + /* STRING */ + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } + break; + + default: + data_type = WBXML_WV_DATA_TYPE_STRING; + break; + } /* switch */ + + + /*********************************************** + * Decode the Opaque, given the Data Type found + */ + + switch ( data_type ) { + case WBXML_WV_DATA_TYPE_INTEGER: + /* Decode Integer */ + if ( (ret = decode_wv_integer(data)) != WBXML_OK ) + return ret; + + return WBXML_OK; + break; + + case WBXML_WV_DATA_TYPE_DATE_AND_TIME: + /* Decode Date and Time */ + if ( (ret = decode_wv_datetime(data)) != WBXML_OK ) + return ret; + + return WBXML_OK; + break; + + case WBXML_WV_DATA_TYPE_BINARY: + /** @todo decode_wv_binary() */ + break; + + default: + /* Do nothing. Keep this data as is. */ + break; + } /* switch */ + + return WBXML_OK; +} + +/** + * @brief Decode a WV Integer encoded in an Opaque + * @param data The WV Integer to decode + * @return WBXML_OK if OK, another error code otherwise + * @note Used for: + * - WV 1.1 / 1.2 + * @note [OMA-WV-CSP_DataTypes-V1_1-20021001-A.pdf] - 4.1: + * "An integer is a number from 0-4294967295 expressed in decimal format." + * + * @warning Input 'data' parameter MUST be a static buffer, because its pointer + * is released without being freed. + */ +static WBXMLError decode_wv_integer(WBXMLBuffer **data) +{ + WB_ULONG i = 0; + WB_ULONG the_int = 0; + WB_UTINY ch = 0; + WB_UTINY tmp[11]; + + if ( (data == NULL) || (*data== NULL) ) + return WBXML_ERROR_INTERNAL; + + /* Get the integer */ + for ( i = 0; i < wbxml_buffer_len(*data); i++ ) { + if (!wbxml_buffer_get_char(*data, i, &ch)) + return WBXML_ERROR_INTERNAL; + + the_int = (the_int << 8) | (ch & 0xff); + } + + /* Check integer overflow */ + if ( the_int > 0xffffffff ) + return WBXML_ERROR_WV_INTEGER_OVERFLOW; + + sprintf((WB_TINY *)tmp, "%u", the_int); + + /* Reset buffer */ + wbxml_buffer_delete(*data, 0, wbxml_buffer_len(*data)); + + /* Set data */ + if (!wbxml_buffer_append_cstr(*data, tmp)) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + return WBXML_OK; +} + + +/** + * @brief Decode a WV Date and Time encoded in an Opaque + * @param data The WV Date Time to decode + * @return WBXML_OK if OK, another error code otherwise + * @note Used for: + * - WV 1.1 / 1.2 + * @note + * Encoded Format: (6 octets) + * - The first 2 bits are reserved, and both must be 0. + * - Year is encoded by 12 bits (0 to 4095) + * - Month is encoded by 4 bits (1 to 12) + * - Day is encoded by 5 bits (1 to 31) + * - Hour is encoded by 5 bits (0 to 23) + * - Minute is encoded by 6 bits (0 to 59) + * - Second is encoded by 6 bits (0 to 59) + * - Time zone is encoded in 1 byte [ISO8601]. + * + * eg: + * Binary: 00 011111010001 1010 10011 01001 110010 011111 01011010 + * Octets: (-------)(-------)(--------)(-------)(-------) (------) + * + * Decoded Format: + * eg: 20011019T095031Z or 20011019T095031 + * + * @warning Input 'data' parameter MUST be a static buffer, because its pointer + * is released without being freed. + */ +static WBXMLError decode_wv_datetime(WBXMLBuffer **data) +{ + WB_UTINY *data_ptr = NULL; + WB_TINY the_year[5], the_month[3], the_date[3], + the_hour[3], the_minute[3], the_second[3], + result[17]; + WB_ULONG the_value = 0; + WBXMLError ret = WBXML_OK; + + /** @todo Test decode_wv_datetime() ! */ + + if ((data == NULL) || (*data == NULL)) + return WBXML_ERROR_INTERNAL; + + if (wbxml_buffer_len(*data) != 6) + return WBXML_ERROR_WV_DATETIME_FORMAT; + + + data_ptr = wbxml_buffer_get_cstr(*data); + + /* Get Year */ + the_value = (WB_ULONG) (((data_ptr[0] & 0x3F) << 6) + ((data_ptr[1] >> 2) & 0x3F)); + sprintf(the_year, "%u", the_value); + + /* Get Month */ + the_value = (WB_ULONG) (((data_ptr[1] & 0x03) << 2) | ((data_ptr[2] >> 6) & 0x03)); + sprintf(the_month, "%02u", the_value); + + /* Get Day */ + the_value = (WB_ULONG) ((data_ptr[2] >> 1) & 0x1F); + sprintf(the_date, "%02u", the_value); + + /* Get Hour */ + the_value = (WB_ULONG) (((data_ptr[2] & 0x01) << 4) | ((data_ptr[3] >> 4) & 0x0F)); + sprintf(the_hour, "%02u", the_value); + + /* Get Minute */ + the_value = (WB_ULONG) (((data_ptr[3] & 0x0F) << 2) | ((data_ptr[4] >> 6) & 0x03)); + sprintf(the_minute, "%02u", the_value); + + /* Get Second */ + the_value = (WB_ULONG) (data_ptr[4] & 0x3F); + sprintf(the_second, "%02u", the_value); + + /* Get Time Zone */ + if (data_ptr[5] == 0) { + /* This is a bug in the WBXML document. + * If timezone UTC aka Zulu is used then a 'Z' must be set. + */ + sprintf((WB_TINY *) result, + "%s%s%sT%s%s%sZ", + the_year, the_month, the_date, the_hour, the_minute, the_value ? the_second : ""); + } else if (data_ptr[5] < 'A' || + data_ptr[5] > 'Z' || + data_ptr[5] == 'J') + { + /* This is a bug in the WBXML document. + * The timezone byte is set and wrong. + * There is no way to recover cleanly from this. + * Therefore no timezone is set. + */ + sprintf((WB_TINY *) result, + "%s%s%sT%s%s%s", + the_year, the_month, the_date, the_hour, the_minute, the_value ? the_second : ""); + } + else { + sprintf((WB_TINY *) result, + "%s%s%sT%s%s%s%c", + the_year, the_month, the_date, the_hour, the_minute, the_value ? the_second : "", data_ptr[5]); + } + + /* Reset buffer */ + wbxml_buffer_delete(*data, 0, wbxml_buffer_len(*data)); + + /* Set data */ + if (!wbxml_buffer_append_cstr(*data, result)) { + ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + return WBXML_OK; +} + +#endif /* WBXML_SUPPORT_WV */ diff --git a/src/wbxml_parser.h b/src/wbxml_parser.h new file mode 100644 index 0000000..8d8ee1c --- /dev/null +++ b/src/wbxml_parser.h @@ -0,0 +1,162 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_parser.h + * @ingroup wbxml_parser + * + * @author Aymerick Jehanne + * @date 02/03/12 + * + * @brief WBXML Parser - Parse a WBXML document and call user defined Callbacks + */ + +#ifndef WBXML_PARSER_H +#define WBXML_PARSER_H + +#include "wbxml.h" +#include "wbxml_handlers.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_parser + * @{ + */ + +/** + * Default charset of the WBXML document. Used only in this case : + * - No charset found in WBXML document + * - No charset was indicated thanks to the function 'wbxml_parser_set_meta_charset()' + */ +#define WBXML_PARSER_DEFAULT_CHARSET WBXML_CHARSET_UTF_8 + + +typedef struct WBXMLParser_s WBXMLParser; + +/** + * @brief Create a WBXML Parser + * @return Return the newly created WBXMLParser, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLParser *) wbxml_parser_create(void); + +/** + * @brief Destroy a WBXML Parser + * @param parser The WBXMLParser to destroy + */ +WBXML_DECLARE(void) wbxml_parser_destroy(WBXMLParser *parser); + +/** + * @brief Parse a WBXML document, using User Defined callbacks + * @param parser The WBXML Parser to use for parsing + * @param wbxml The WBXML document to parse + * @param wbxml_len The WBXML document length + * @brief Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_parser_parse(WBXMLParser *parser, WB_UTINY *wbxml, WB_ULONG wbxml_len); + +/** + * @brief Set User Data for a WBXML Parser + * @param parser The WBXML Parser + * @param user_data User data (returned as a parameter in every Content Handler callbacks) + */ +WBXML_DECLARE(void) wbxml_parser_set_user_data(WBXMLParser *parser, void *user_data); + +/** + * @brief Set Content Handler for a WBXML Parser + * @param parser The WBXML Parser + * @param content_handler The Content Handler structure + */ +WBXML_DECLARE(void) wbxml_parser_set_content_handler(WBXMLParser *parser, WBXMLContentHandler *content_handler); + +/** + * @brief Set Main WBXML Languages Table + * @param parser The WBXML Parser + * @param main_table The Main WBXML Languages Table to set + */ +WBXML_DECLARE(void) wbxml_parser_set_main_table(WBXMLParser *parser, const WBXMLLangEntry *main_table); + +/** + * @brief Force to parse the Document of a given Language + * @param parser The WBXML Parser + * @param lang The Language + * @return TRUE if Language is set, FALSE otherwise + * @note This permits to force the WBXML Parser to parse a WBXML Document of a given LanguageD. + * If this fonction is used, the internal Public ID of the WBXML Document is ignored. + * It is sometimes needed for documents that don't have any WBXML Public ID. + */ +WBXML_DECLARE(WB_BOOL) wbxml_parser_set_language(WBXMLParser *parser, WBXMLLanguage lang); + +/** + * @brief Set additionnal meta-information to help determining the Charset Encoding of the Document to parse + * @param parser The WBXML Parser + * @param charset The Charset MIBEnum + * @return TRUE if Charset is set, FALSE otherwise + * @note This information is only used if the Charset Encoding is not specified in WBXML Document: + * "The binary XML format contains a representation of the XML document character encoding. + * This is the WBXML equivalent of the XML document format encoding attribute, + * which is specified in the ?xml processing instruction ... In the case of + * an unknown encoding, transport meta-information should be used to determine the character + * encoding. If transport meta-information is unavailable, the default encoding of UTF-8 + * should be assumed." + */ +WBXML_DECLARE(WB_BOOL) wbxml_parser_set_meta_charset(WBXMLParser *parser, WBXMLCharsetMIBEnum charset); + +/** + * @brief Get WBXML Public ID + * @param parser The WBXML Parser + * @return The WBXML Public ID of current parsing document + */ +WBXML_DECLARE(WB_ULONG) wbxml_parser_get_wbxml_public_id(WBXMLParser *parser); + +/** + * @brief Get XML Public ID + * @param parser The WBXML Parser + * @return The XML Public ID of current parsing document, or NULL if not found + */ +WBXML_DECLARE(const WB_UTINY *) wbxml_parser_get_xml_public_id(WBXMLParser *parser); + +/** + * @brief Get WBXML Version + * @param parser The WBXML Parser + * @return The WBXML Version of current parsing document + */ +WBXML_DECLARE(WBXMLVersion) wbxml_parser_get_wbxml_version(WBXMLParser *parser); + +/** + * @brief Return current parsing position in WBXML + * @param parser The WBXML Parser + * @return The parsing position in WBXML + */ +WBXML_DECLARE(WB_LONG) wbxml_parser_get_current_byte_index(WBXMLParser *parser); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_PARSER_H */ diff --git a/src/wbxml_tables.c b/src/wbxml_tables.c new file mode 100644 index 0000000..64082111 --- /dev/null +++ b/src/wbxml_tables.c @@ -0,0 +1,3851 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2008-2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_tables.c + * @ingroup wbxml_tables + * + * @author Aymerick Jehanne + * @date 02/03/17 + * + * @brief WBXML Tables + */ + +#include "wbxml_tables.h" +#include "wbxml_internals.h" +#include "wbxml_log.h" + +/** + * @brief If undefined, only the WML 1.3 tables are used for all WML versions (WML 1.0 / WML 1.1 / WML 1.2 / WML 1.3). + * It saves space, and, well, every handset must supports WML 1.3 right now. + * If defined, each version has its own exact tables. + */ +#undef WBXML_TABLES_SEPARATE_WML_VERSIONS + + +/************************************** + * Languages Public IDs + */ + +/* WAP */ +#if defined( WBXML_SUPPORT_WML ) +const WBXMLPublicIDEntry sv_wml10_public_id = { WBXML_PUBLIC_ID_WML10, XML_PUBLIC_ID_WML10, "wml", "http://www.wapforum.org/DTD/wml.xml" }; +const WBXMLPublicIDEntry sv_wml11_public_id = { WBXML_PUBLIC_ID_WML11, XML_PUBLIC_ID_WML11, "wml", "http://www.wapforum.org/DTD/wml_1_1.dtd" }; +const WBXMLPublicIDEntry sv_wml12_public_id = { WBXML_PUBLIC_ID_WML12, XML_PUBLIC_ID_WML12, "wml", "http://www.wapforum.org/DTD/wml12.dtd" }; +const WBXMLPublicIDEntry sv_wml13_public_id = { WBXML_PUBLIC_ID_WML13, XML_PUBLIC_ID_WML13, "wml", "http://www.wapforum.org/DTD/wml13.dtd" }; +#endif /* WBXML_SUPPORT_WML */ + +#if defined( WBXML_SUPPORT_WTA ) +const WBXMLPublicIDEntry sv_wta10_public_id = { WBXML_PUBLIC_ID_WTA10, XML_PUBLIC_ID_WTA10, "wtai", "wtai.dtd" }; +const WBXMLPublicIDEntry sv_wtawml12_public_id = { WBXML_PUBLIC_ID_WTAWML12, XML_PUBLIC_ID_WTAWML12, "wta-wml", "http://www.wapforum.org/DTD/wta-wml12.dtd" }; +const WBXMLPublicIDEntry sv_channel11_public_id = { WBXML_PUBLIC_ID_CHANNEL11, XML_PUBLIC_ID_CHANNEL11, "channel", "" }; +const WBXMLPublicIDEntry sv_channel12_public_id = { WBXML_PUBLIC_ID_CHANNEL12, XML_PUBLIC_ID_CHANNEL12, "channel", "http://www.wapforum.org/DTD/channel12.dtd" }; +#endif /* WBXML_SUPPORT_WTA */ + +#if defined( WBXML_SUPPORT_SI ) +const WBXMLPublicIDEntry sv_si10_public_id = { WBXML_PUBLIC_ID_SI10, XML_PUBLIC_ID_SI10, "si", "http://www.wapforum.org/DTD/si.dtd" }; +#endif /* WBXML_SUPPORT_SI */ + +#if defined( WBXML_SUPPORT_SL ) +const WBXMLPublicIDEntry sv_sl10_public_id = { WBXML_PUBLIC_ID_SL10, XML_PUBLIC_ID_SL10, "sl", "http://www.wapforum.org/DTD/sl.dtd" }; +#endif /* WBXML_SUPPORT_SL */ + +#if defined( WBXML_SUPPORT_CO ) +const WBXMLPublicIDEntry sv_co10_public_id = { WBXML_PUBLIC_ID_CO10, XML_PUBLIC_ID_CO10, "co", "http://www.wapforum.org/DTD/co_1.0.dtd" }; +#endif /* WBXML_SUPPORT_CO */ + +#if defined( WBXML_SUPPORT_PROV ) +const WBXMLPublicIDEntry sv_prov10_public_id = { WBXML_PUBLIC_ID_PROV10, XML_PUBLIC_ID_PROV10, "wap-provisioningdoc", "http://www.wapforum.org/DTD/prov.dtd" }; +#endif /* WBXML_SUPPORT_PROV */ + +#if defined( WBXML_SUPPORT_EMN ) +const WBXMLPublicIDEntry sv_emn10_public_id = { WBXML_PUBLIC_ID_EMN10, XML_PUBLIC_ID_EMN10, "emn", "http://www.wapforum.org/DTD/emn.dtd" }; +#endif /* WBXML_SUPPORT_EMN */ + +#if defined( WBXML_SUPPORT_DRMREL ) +const WBXMLPublicIDEntry sv_drmrel10_public_id = { WBXML_PUBLIC_ID_DRMREL10, XML_PUBLIC_ID_DRMREL10, "o-ex:rights", "http://www.openmobilealliance.org/DTD/drmrel10.dtd"}; +#endif /* WBXML_SUPPORT_DRMREL */ + +#if defined( WBXML_SUPPORT_OTA_SETTINGS ) +/* Ericsson / Nokia OTA Settings v7.0 */ +const WBXMLPublicIDEntry sv_ota_settings_public_id = { WBXML_PUBLIC_ID_OTA_SETTINGS, XML_PUBLIC_ID_OTA_SETTINGS, "CHARACTERISTIC-LIST", "characteristic-list.dtd" }; +#endif /* WBXML_SUPPORT_OTA_SETTINGS */ + +#if defined( WBXML_SUPPORT_SYNCML ) +/* SyncML 1.0 */ +const WBXMLPublicIDEntry sv_syncml_syncml10_public_id = { WBXML_PUBLIC_ID_SYNCML_SYNCML10, XML_PUBLIC_ID_SYNCML_SYNCML10, "SyncML", "http://www.syncml.org/docs/syncml_represent_v10_20001207.dtd" }; +const WBXMLPublicIDEntry sv_syncml_devinf10_public_id = { WBXML_PUBLIC_ID_SYNCML_DEVINF10, XML_PUBLIC_ID_SYNCML_DEVINF10, "DevInf", "http://www.syncml.org/docs/syncml_devinf_v10_20001207.dtd" }; +const WBXMLPublicIDEntry sv_syncml_metinf10_public_id = { WBXML_PUBLIC_ID_SYNCML_METINF10, XML_PUBLIC_ID_SYNCML_METINF10, "MetInf", "http://www.syncml.org/docs/syncml_metinf_v10_20001207.dtd" }; + +/* SyncML 1.1 */ +const WBXMLPublicIDEntry sv_syncml_syncml11_public_id = { WBXML_PUBLIC_ID_SYNCML_SYNCML11, XML_PUBLIC_ID_SYNCML_SYNCML11, "SyncML", "http://www.syncml.org/docs/syncml_represent_v11_20020213.dtd" }; +const WBXMLPublicIDEntry sv_syncml_devinf11_public_id = { WBXML_PUBLIC_ID_SYNCML_DEVINF11, XML_PUBLIC_ID_SYNCML_DEVINF11, "DevInf", "http://www.syncml.org/docs/devinf_v11_20020215.dtd" }; +const WBXMLPublicIDEntry sv_syncml_metinf11_public_id = { WBXML_PUBLIC_ID_SYNCML_METINF11, XML_PUBLIC_ID_SYNCML_METINF11, "MetInf", "http://www.syncml.org/docs/syncml_metinf_v11_20020215.dtd" }; + +/* SyncML 1.2 */ +const WBXMLPublicIDEntry sv_syncml_syncml12_public_id = { WBXML_PUBLIC_ID_SYNCML_SYNCML12, XML_PUBLIC_ID_SYNCML_SYNCML12, "SyncML", "http://www.openmobilealliance.org/tech/DTD/OMA-TS-SyncML_RepPro_DTD-V1_2.dtd" }; +const WBXMLPublicIDEntry sv_syncml_devinf12_public_id = { WBXML_PUBLIC_ID_SYNCML_DEVINF12, XML_PUBLIC_ID_SYNCML_DEVINF12, "DevInf", "http://www.openmobilealliance.org/tech/DTD/OMA-SyncML-Device_Information-DTD-1.2.dtd" }; +const WBXMLPublicIDEntry sv_syncml_metinf12_public_id = { WBXML_PUBLIC_ID_SYNCML_METINF12, XML_PUBLIC_ID_SYNCML_METINF12, "MetInf", "http://www.openmobilealliance.org/tech/DTD/OMA-TS-SyncML_MetaInfo_DTD-V1_2.dtd" }; +const WBXMLPublicIDEntry sv_syncml_dmddf12_public_id = { WBXML_PUBLIC_ID_SYNCML_DMDDF12, XML_PUBLIC_ID_SYNCML_DMDDF12, "MgmtTree", "http://www.openmobilealliance.org/tech/DTD/dm_ddf-v1_2.dtd" }; +#endif /* WBXML_SUPPORT_SYNCML */ + +#if defined( WBXML_SUPPORT_WV ) +/* OMA Wireless Village CSP 1.1 / 1.2 */ +const WBXMLPublicIDEntry sv_wv_csp11_public_id = { WBXML_PUBLIC_ID_WV_CSP11, XML_PUBLIC_ID_WV_CSP11, "WV-CSP-Message", "http://www.openmobilealliance.org/DTD/WV-CSP.XML" }; +const WBXMLPublicIDEntry sv_wv_csp12_public_id = { WBXML_PUBLIC_ID_WV_CSP12, XML_PUBLIC_ID_WV_CSP12, "WV-CSP-Message", "http://www.openmobilealliance.org/DTD/WV-CSP.DTD" }; +#endif /* WBXML_SUPPORT_WV */ + +#if defined( WBXML_SUPPORT_AIRSYNC ) +const WBXMLPublicIDEntry sv_airsync_public_id = { WBXML_PUBLIC_ID_AIRSYNC, XML_PUBLIC_ID_AIRSYNC, "AirSync", "http://www.microsoft.com/"}; +const WBXMLPublicIDEntry sv_activesync_public_id = { WBXML_PUBLIC_ID_ACTIVESYNC, XML_PUBLIC_ID_ACTIVESYNC, "ActiveSync", "http://www.microsoft.com/"}; +#endif /* WBXML_SUPPORT_AIRSYNC */ + +#if defined( WBXML_SUPPORT_CONML ) +const WBXMLPublicIDEntry sv_conml_public_id = { WBXML_PUBLIC_ID_CONML, XML_PUBLIC_ID_CONML, "ConML", "http://www.nokia.com/"}; +#endif /* WBXML_SUPPORT_CONML */ + + +/************************************** + * Languages Tables + */ + +#if defined( WBXML_SUPPORT_WML ) + +#ifdef WBXML_TABLES_SEPARATE_WML_VERSIONS + +/******************************************** + * WML 1.0 (WAP 1.0: "WML-30-Apr-98.pdf") + */ + +const WBXMLTagEntry sv_wml10_tag_table[] = { + { "a", 0x00, 0x22 }, + { "access", 0x00, 0x23 }, + { "b", 0x00, 0x24 }, + { "big", 0x00, 0x25 }, + { "br", 0x00, 0x26 }, + { "card", 0x00, 0x27 }, + { "do", 0x00, 0x28 }, + { "em", 0x00, 0x29 }, + { "fieldset", 0x00, 0x2a }, + { "go", 0x00, 0x2b }, + { "head", 0x00, 0x2c }, + { "i", 0x00, 0x2d }, + { "img", 0x00, 0x2e }, + { "input", 0x00, 0x2f }, + { "meta", 0x00, 0x30 }, + { "noop", 0x00, 0x31 }, + { "prev", 0x00, 0x32 }, + { "onevent", 0x00, 0x33 }, + { "optgroup", 0x00, 0x34 }, + { "option", 0x00, 0x35 }, + { "refresh", 0x00, 0x36 }, + { "select", 0x00, 0x37 }, + { "small", 0x00, 0x38 }, + { "strong", 0x00, 0x39 }, + { "tab", 0x00, 0x3a }, /* Deprecated */ + { "template", 0x00, 0x3b }, + { "timer", 0x00, 0x3c }, + { "u", 0x00, 0x3d }, + { "var", 0x00, 0x3e }, + { "wml", 0x00, 0x3f }, + { NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrEntry sv_wml10_attr_table[] = { + { "accept-charset", NULL, 0x00, 0x05 }, + { "align", "bottom", 0x00, 0x06 }, + { "align", "center", 0x00, 0x07 }, + { "align", "left", 0x00, 0x08 }, + { "align", "middle", 0x00, 0x09 }, + { "align", "right", 0x00, 0x0a }, + { "align", "top", 0x00, 0x0b }, + { "alt", NULL, 0x00, 0x0c }, + { "content", NULL, 0x00, 0x0d }, + { "default", NULL, 0x00, 0x0e }, + { "domain", NULL, 0x00, 0x0f }, + { "emptyok", "false", 0x00, 0x10 }, + { "emptyok", "true", 0x00, 0x11 }, + { "format", NULL, 0x00, 0x12 }, + { "height", NULL, 0x00, 0x13 }, + { "hspace", NULL, 0x00, 0x14 }, + { "idefault", NULL, 0x00, 0x15 }, /* Deprecated */ + { "ikey", NULL, 0x00, 0x16 }, /* Deprecated */ + { "key", NULL, 0x00, 0x17 }, /* Deprecated */ + { "label", NULL, 0x00, 0x18 }, + { "localsrc", NULL, 0x00, 0x19 }, + { "maxlength", NULL, 0x00, 0x1a }, + { "method", "get", 0x00, 0x1b }, + { "method", "post", 0x00, 0x1c }, + { "mode", "nowrap", 0x00, 0x1d }, + { "mode", "wrap", 0x00, 0x1e }, + { "multiple", "false", 0x00, 0x1f }, + { "multiple", "true", 0x00, 0x20 }, + { "name", NULL, 0x00, 0x21 }, + { "newcontext", "false", 0x00, 0x22 }, + { "newcontext", "true", 0x00, 0x23 }, + { "onclick", NULL, 0x00, 0x24 }, /* Deprecated */ + { "onenterbackward", NULL, 0x00, 0x25 }, + { "onenterforward", NULL, 0x00, 0x26 }, + { "ontimer", NULL, 0x00, 0x27 }, + { "optional", "false", 0x00, 0x28 }, + { "optional", "true", 0x00, 0x29 }, + { "path", NULL, 0x00, 0x2a }, + { "postdata", NULL, 0x00, 0x2b }, /* Deprecated */ + { "public", "false", 0x00, 0x2c }, /* Deprecated */ + { "public", "true", 0x00, 0x2d }, /* Deprecated */ + { "scheme", NULL, 0x00, 0x2e }, + { "sendreferer", "false", 0x00, 0x2f }, + { "sendreferer", "true", 0x00, 0x30 }, + { "size", NULL, 0x00, 0x31 }, + { "src", NULL, 0x00, 0x32 }, + { "style", "list", 0x00, 0x33 }, /* Deprecated */ + { "style", "set", 0x00, 0x34 }, /* Deprecated */ + { "tabindex", NULL, 0x00, 0x35 }, + { "title", NULL, 0x00, 0x36 }, + { "type", NULL, 0x00, 0x37 }, + { "type", "accept", 0x00, 0x38 }, + { "type", "delete", 0x00, 0x39 }, + { "type", "help", 0x00, 0x3a }, + { "type", "password", 0x00, 0x3b }, + { "type", "onpick", 0x00, 0x3c }, + { "type", "onenterbackward", 0x00, 0x3d }, + { "type", "onenterforward", 0x00, 0x3e }, + { "type", "ontimer", 0x00, 0x3f }, + { "type", "options", 0x00, 0x45 }, + { "type", "prev", 0x00, 0x46 }, + { "type", "reset", 0x00, 0x47 }, + { "type", "text", 0x00, 0x48 }, + { "type", "vnd.", 0x00, 0x49 }, + { "url", NULL, 0x00, 0x4a }, /* Deprecated */ + { "url", "http://", 0x00, 0x4b }, /* Deprecated */ + { "url", "https://", 0x00, 0x4c }, /* Deprecated */ + { "user-agent", NULL, 0x00, 0x4d }, /* Deprecated */ + { "value", NULL, 0x00, 0x4e }, + { "vspace", NULL, 0x00, 0x4f }, + { "width", NULL, 0x00, 0x50 }, + { "xml:lang", NULL, 0x00, 0x51 }, + { NULL, NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrValueEntry sv_wml10_attr_value_table[] = { + { ".com/", 0x00, 0x85 }, + { ".edu/", 0x00, 0x86 }, + { ".net/", 0x00, 0x87 }, + { ".org/", 0x00, 0x88 }, + { "accept", 0x00, 0x89 }, + { "bottom", 0x00, 0x8a }, + { "clear", 0x00, 0x8b }, + { "delete", 0x00, 0x8c }, + { "help", 0x00, 0x8d }, + /* Do NOT change the order in this table please ! */ + { "http://www.", 0x00, 0x8f }, + { "http://", 0x00, 0x8e }, + { "https://www.", 0x00, 0x91 }, + { "https://", 0x00, 0x90 }, + { "list", 0x00, 0x92 }, /* Deprecated */ + { "middle", 0x00, 0x93 }, + { "nowrap", 0x00, 0x94 }, + { "onclick", 0x00, 0x95 }, /* Deprecated */ + { "onenterbackward", 0x00, 0x96 }, + { "onenterforward", 0x00, 0x97 }, + { "ontimer", 0x00, 0x98 }, + { "options", 0x00, 0x99 }, + { "password", 0x00, 0x9a }, + { "reset", 0x00, 0x9b }, + { "set", 0x00, 0x9c }, /* Deprecated */ + { "text", 0x00, 0x9d }, + { "top", 0x00, 0x9e }, + { "unknown", 0x00, 0x9f }, + { "wrap", 0x00, 0xa0 }, + { "www.", 0x00, 0xa1 }, + { NULL, 0x00, 0x00 } +}; + + +/*********************************************** + * WML 1.1 (WAP 1.1: "SPEC-WML-19990616.pdf") + */ + +const WBXMLTagEntry sv_wml11_tag_table[] = { + { "a", 0x00, 0x1c }, + { "anchor", 0x00, 0x22 }, /* WML 1.1 */ + { "access", 0x00, 0x23 }, + { "b", 0x00, 0x24 }, + { "big", 0x00, 0x25 }, + { "br", 0x00, 0x26 }, + { "card", 0x00, 0x27 }, + { "do", 0x00, 0x28 }, + { "em", 0x00, 0x29 }, + { "fieldset", 0x00, 0x2a }, + { "go", 0x00, 0x2b }, + { "head", 0x00, 0x2c }, + { "i", 0x00, 0x2d }, + { "img", 0x00, 0x2e }, + { "input", 0x00, 0x2f }, + { "meta", 0x00, 0x30 }, + { "noop", 0x00, 0x31 }, + { "p", 0x00, 0x20 }, /* WML 1.1 */ + { "postfield", 0x00, 0x21 }, /* WML 1.1 */ + { "prev", 0x00, 0x32 }, + { "onevent", 0x00, 0x33 }, + { "optgroup", 0x00, 0x34 }, + { "option", 0x00, 0x35 }, + { "refresh", 0x00, 0x36 }, + { "select", 0x00, 0x37 }, + { "setvar", 0x00, 0x3e }, /* WML 1.1 */ + { "small", 0x00, 0x38 }, + { "strong", 0x00, 0x39 }, + { "table", 0x00, 0x1f }, /* WML 1.1 */ + { "td", 0x00, 0x1d }, /* WML 1.1 */ + { "template", 0x00, 0x3b }, + { "timer", 0x00, 0x3c }, + { "tr", 0x00, 0x1e }, /* WML 1.1 */ + { "u", 0x00, 0x3d }, + { "wml", 0x00, 0x3f }, + { NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrEntry sv_wml11_attr_table[] = { + { "accept-charset", NULL, 0x00, 0x05 }, + { "align", NULL, 0x00, 0x52 }, /* WML 1.1 */ + { "align", "bottom", 0x00, 0x06 }, + { "align", "center", 0x00, 0x07 }, + { "align", "left", 0x00, 0x08 }, + { "align", "middle", 0x00, 0x09 }, + { "align", "right", 0x00, 0x0a }, + { "align", "top", 0x00, 0x0b }, + { "alt", NULL, 0x00, 0x0c }, + { "class", NULL, 0x00, 0x54 }, /* WML 1.1 */ + { "columns", NULL, 0x00, 0x53 }, /* WML 1.1 */ + { "content", NULL, 0x00, 0x0d }, + { "content", "application/vnd.wap.wmlc;charset=", 0x00, 0x5c }, /* WML 1.1 */ + { "domain", NULL, 0x00, 0x0f }, + { "emptyok", "false", 0x00, 0x10 }, + { "emptyok", "true", 0x00, 0x11 }, + { "format", NULL, 0x00, 0x12 }, + { "forua", "false", 0x00, 0x56 }, /* WML 1.1 */ + { "forua", "true", 0x00, 0x57 }, /* WML 1.1 */ + { "height", NULL, 0x00, 0x13 }, + { "href", NULL, 0x00, 0x4a }, /* WML 1.1 */ + { "href", "http://", 0x00, 0x4b }, /* WML 1.1 */ + { "href", "https://", 0x00, 0x4c }, /* WML 1.1 */ + { "hspace", NULL, 0x00, 0x14 }, + { "http-equiv", NULL, 0x00, 0x5a }, /* WML 1.1 */ + { "http-equiv", "Content-Type", 0x00, 0x5b }, /* WML 1.1 */ + { "http-equiv", "Expires", 0x00, 0x5d }, /* WML 1.1 */ + { "id", NULL, 0x00, 0x55 }, /* WML 1.1 */ + { "ivalue", NULL, 0x00, 0x15 }, /* WML 1.1 */ + { "iname", NULL, 0x00, 0x16 }, /* WML 1.1 */ + { "label", NULL, 0x00, 0x18 }, + { "localsrc", NULL, 0x00, 0x19 }, + { "maxlength", NULL, 0x00, 0x1a }, + { "method", "get", 0x00, 0x1b }, + { "method", "post", 0x00, 0x1c }, + { "mode", "nowrap", 0x00, 0x1d }, + { "mode", "wrap", 0x00, 0x1e }, + { "multiple", "false", 0x00, 0x1f }, + { "multiple", "true", 0x00, 0x20 }, + { "name", NULL, 0x00, 0x21 }, + { "newcontext", "false", 0x00, 0x22 }, + { "newcontext", "true", 0x00, 0x23 }, + { "onenterbackward", NULL, 0x00, 0x25 }, + { "onenterforward", NULL, 0x00, 0x26 }, + { "onpick", NULL, 0x00, 0x24 }, /* WML 1.1 */ + { "ontimer", NULL, 0x00, 0x27 }, + { "optional", "false", 0x00, 0x28 }, + { "optional", "true", 0x00, 0x29 }, + { "path", NULL, 0x00, 0x2a }, + { "scheme", NULL, 0x00, 0x2e }, + { "sendreferer", "false", 0x00, 0x2f }, + { "sendreferer", "true", 0x00, 0x30 }, + { "size", NULL, 0x00, 0x31 }, + { "src", NULL, 0x00, 0x32 }, + { "src", "http://", 0x00, 0x58 }, /* WML 1.1 */ + { "src", "https://", 0x00, 0x59 }, /* WML 1.1 */ + { "ordered", "true", 0x00, 0x33 }, /* WML 1.1 */ + { "ordered", "false", 0x00, 0x34 }, /* WML 1.1 */ + { "tabindex", NULL, 0x00, 0x35 }, + { "title", NULL, 0x00, 0x36 }, + { "type", NULL, 0x00, 0x37 }, + { "type", "accept", 0x00, 0x38 }, + { "type", "delete", 0x00, 0x39 }, + { "type", "help", 0x00, 0x3a }, + { "type", "password", 0x00, 0x3b }, + { "type", "onpick", 0x00, 0x3c }, + { "type", "onenterbackward", 0x00, 0x3d }, + { "type", "onenterforward", 0x00, 0x3e }, + { "type", "ontimer", 0x00, 0x3f }, + { "type", "options", 0x00, 0x45 }, + { "type", "prev", 0x00, 0x46 }, + { "type", "reset", 0x00, 0x47 }, + { "type", "text", 0x00, 0x48 }, + { "type", "vnd.", 0x00, 0x49 }, + { "value", NULL, 0x00, 0x4d }, + { "vspace", NULL, 0x00, 0x4e }, + { "width", NULL, 0x00, 0x4f }, + { "xml:lang", NULL, 0x00, 0x50 }, + { NULL, NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrValueEntry sv_wml11_attr_value_table[] = { + { ".com/", 0x00, 0x85 }, + { ".edu/", 0x00, 0x86 }, + { ".net/", 0x00, 0x87 }, + { ".org/", 0x00, 0x88 }, + { "accept", 0x00, 0x89 }, + { "bottom", 0x00, 0x8a }, + { "clear", 0x00, 0x8b }, + { "delete", 0x00, 0x8c }, + { "help", 0x00, 0x8d }, + /* Do NOT change the order in this table please ! */ + { "http://www.", 0x00, 0x8f }, + { "http://", 0x00, 0x8e }, + { "https://www.", 0x00, 0x91 }, + { "https://", 0x00, 0x90 }, + { "middle", 0x00, 0x93 }, + { "nowrap", 0x00, 0x94 }, + { "onenterbackward", 0x00, 0x96 }, + { "onenterforward", 0x00, 0x97 }, + { "onpick", 0x00, 0x95 }, /* WML 1.1 */ + { "ontimer", 0x00, 0x98 }, + { "options", 0x00, 0x99 }, + { "password", 0x00, 0x9a }, + { "reset", 0x00, 0x9b }, + { "text", 0x00, 0x9d }, + { "top", 0x00, 0x9e }, + { "unknown", 0x00, 0x9f }, + { "wrap", 0x00, 0xa0 }, + { "www.", 0x00, 0xa1 }, + { NULL, 0x00, 0x00 } +}; + + +/*********************************************** + * WML 1.2 (WAP 1.2: "SPEC-WML-19991104.pdf") + */ + +const WBXMLTagEntry sv_wml12_tag_table[] = { + { "a", 0x00, 0x1c }, + { "anchor", 0x00, 0x22 }, + { "access", 0x00, 0x23 }, + { "b", 0x00, 0x24 }, + { "big", 0x00, 0x25 }, + { "br", 0x00, 0x26 }, + { "card", 0x00, 0x27 }, + { "do", 0x00, 0x28 }, + { "em", 0x00, 0x29 }, + { "fieldset", 0x00, 0x2a }, + { "go", 0x00, 0x2b }, + { "head", 0x00, 0x2c }, + { "i", 0x00, 0x2d }, + { "img", 0x00, 0x2e }, + { "input", 0x00, 0x2f }, + { "meta", 0x00, 0x30 }, + { "noop", 0x00, 0x31 }, + { "p", 0x00, 0x20 }, + { "postfield", 0x00, 0x21 }, + { "pre", 0x00, 0x1b }, + { "prev", 0x00, 0x32 }, + { "onevent", 0x00, 0x33 }, + { "optgroup", 0x00, 0x34 }, + { "option", 0x00, 0x35 }, + { "refresh", 0x00, 0x36 }, + { "select", 0x00, 0x37 }, + { "setvar", 0x00, 0x3e }, + { "small", 0x00, 0x38 }, + { "strong", 0x00, 0x39 }, + { "table", 0x00, 0x1f }, + { "td", 0x00, 0x1d }, + { "template", 0x00, 0x3b }, + { "timer", 0x00, 0x3c }, + { "tr", 0x00, 0x1e }, + { "u", 0x00, 0x3d }, + { "wml", 0x00, 0x3f }, + { NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrEntry sv_wml12_attr_table[] = { + { "accept-charset", NULL, 0x00, 0x05 }, + { "accesskey", NULL, 0x00, 0x5e }, /* WML 1.2 */ + { "align", NULL, 0x00, 0x52 }, + { "align", "bottom", 0x00, 0x06 }, + { "align", "center", 0x00, 0x07 }, + { "align", "left", 0x00, 0x08 }, + { "align", "middle", 0x00, 0x09 }, + { "align", "right", 0x00, 0x0a }, + { "align", "top", 0x00, 0x0b }, + { "alt", NULL, 0x00, 0x0c }, + { "class", NULL, 0x00, 0x54 }, + { "columns", NULL, 0x00, 0x53 }, + { "content", NULL, 0x00, 0x0d }, + { "content", "application/vnd.wap.wmlc;charset=", 0x00, 0x5c }, + { "domain", NULL, 0x00, 0x0f }, + { "emptyok", "false", 0x00, 0x10 }, + { "emptyok", "true", 0x00, 0x11 }, + { "enctype", NULL, 0x00, 0x5f }, /* WML 1.2 */ + { "enctype", "application/x-www-form-urlencoded", 0x00, 0x60 }, /* WML 1.2 */ + { "enctype", "multipart/form-data", 0x00, 0x61 }, /* WML 1.2 */ + { "format", NULL, 0x00, 0x12 }, + { "forua", "false", 0x00, 0x56 }, + { "forua", "true", 0x00, 0x57 }, + { "height", NULL, 0x00, 0x13 }, + { "href", NULL, 0x00, 0x4a }, + { "href", "http://", 0x00, 0x4b }, + { "href", "https://", 0x00, 0x4c }, + { "hspace", NULL, 0x00, 0x14 }, + { "http-equiv", NULL, 0x00, 0x5a }, + { "http-equiv", "Content-Type", 0x00, 0x5b }, + { "http-equiv", "Expires", 0x00, 0x5d }, + { "id", NULL, 0x00, 0x55 }, + { "ivalue", NULL, 0x00, 0x15 }, + { "iname", NULL, 0x00, 0x16 }, + { "label", NULL, 0x00, 0x18 }, + { "localsrc", NULL, 0x00, 0x19 }, + { "maxlength", NULL, 0x00, 0x1a }, + { "method", "get", 0x00, 0x1b }, + { "method", "post", 0x00, 0x1c }, + { "mode", "nowrap", 0x00, 0x1d }, + { "mode", "wrap", 0x00, 0x1e }, + { "multiple", "false", 0x00, 0x1f }, + { "multiple", "true", 0x00, 0x20 }, + { "name", NULL, 0x00, 0x21 }, + { "newcontext", "false", 0x00, 0x22 }, + { "newcontext", "true", 0x00, 0x23 }, + { "onenterbackward", NULL, 0x00, 0x25 }, + { "onenterforward", NULL, 0x00, 0x26 }, + { "onpick", NULL, 0x00, 0x24 }, + { "ontimer", NULL, 0x00, 0x27 }, + { "optional", "false", 0x00, 0x28 }, + { "optional", "true", 0x00, 0x29 }, + { "path", NULL, 0x00, 0x2a }, + { "scheme", NULL, 0x00, 0x2e }, + { "sendreferer", "false", 0x00, 0x2f }, + { "sendreferer", "true", 0x00, 0x30 }, + { "size", NULL, 0x00, 0x31 }, + { "src", NULL, 0x00, 0x32 }, + { "src", "http://", 0x00, 0x58 }, + { "src", "https://", 0x00, 0x59 }, + { "ordered", "true", 0x00, 0x33 }, + { "ordered", "false", 0x00, 0x34 }, + { "tabindex", NULL, 0x00, 0x35 }, + { "title", NULL, 0x00, 0x36 }, + { "type", NULL, 0x00, 0x37 }, + { "type", "accept", 0x00, 0x38 }, + { "type", "delete", 0x00, 0x39 }, + { "type", "help", 0x00, 0x3a }, + { "type", "password", 0x00, 0x3b }, + { "type", "onpick", 0x00, 0x3c }, + { "type", "onenterbackward", 0x00, 0x3d }, + { "type", "onenterforward", 0x00, 0x3e }, + { "type", "ontimer", 0x00, 0x3f }, + { "type", "options", 0x00, 0x45 }, + { "type", "prev", 0x00, 0x46 }, + { "type", "reset", 0x00, 0x47 }, + { "type", "text", 0x00, 0x48 }, + { "type", "vnd.", 0x00, 0x49 }, + { "value", NULL, 0x00, 0x4d }, + { "vspace", NULL, 0x00, 0x4e }, + { "width", NULL, 0x00, 0x4f }, + { "xml:lang", NULL, 0x00, 0x50 }, + { NULL, NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrValueEntry sv_wml12_attr_value_table[] = { + { ".com/", 0x00, 0x85 }, + { ".edu/", 0x00, 0x86 }, + { ".net/", 0x00, 0x87 }, + { ".org/", 0x00, 0x88 }, + { "accept", 0x00, 0x89 }, + { "bottom", 0x00, 0x8a }, + { "clear", 0x00, 0x8b }, + { "delete", 0x00, 0x8c }, + { "help", 0x00, 0x8d }, + /* Do NOT change the order in this table please ! */ + { "http://www.", 0x00, 0x8f }, + { "http://", 0x00, 0x8e }, + { "https://www.", 0x00, 0x91 }, + { "https://", 0x00, 0x90 }, + { "middle", 0x00, 0x93 }, + { "nowrap", 0x00, 0x94 }, + { "onenterbackward", 0x00, 0x96 }, + { "onenterforward", 0x00, 0x97 }, + { "onpick", 0x00, 0x95 }, + { "ontimer", 0x00, 0x98 }, + { "options", 0x00, 0x99 }, + { "password", 0x00, 0x9a }, + { "reset", 0x00, 0x9b }, + { "text", 0x00, 0x9d }, + { "top", 0x00, 0x9e }, + { "unknown", 0x00, 0x9f }, + { "wrap", 0x00, 0xa0 }, + { "www.", 0x00, 0xa1 }, + { NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_TABLES_SEPARATE_WML_VERSIONS */ + + +/****************************************************** + * WML 1.3 (WAP 1.2.1: "WAP-191-WML-20000219-a.pdf") + */ + +const WBXMLTagEntry sv_wml13_tag_table[] = { + { "a", 0x00, 0x1c }, + { "anchor", 0x00, 0x22 }, /* WML 1.1 */ + { "access", 0x00, 0x23 }, + { "b", 0x00, 0x24 }, + { "big", 0x00, 0x25 }, + { "br", 0x00, 0x26 }, + { "card", 0x00, 0x27 }, + { "do", 0x00, 0x28 }, + { "em", 0x00, 0x29 }, + { "fieldset", 0x00, 0x2a }, + { "go", 0x00, 0x2b }, + { "head", 0x00, 0x2c }, + { "i", 0x00, 0x2d }, + { "img", 0x00, 0x2e }, + { "input", 0x00, 0x2f }, + { "meta", 0x00, 0x30 }, + { "noop", 0x00, 0x31 }, + { "p", 0x00, 0x20 }, /* WML 1.1 */ + { "postfield", 0x00, 0x21 }, /* WML 1.1 */ + { "pre", 0x00, 0x1b }, + { "prev", 0x00, 0x32 }, + { "onevent", 0x00, 0x33 }, + { "optgroup", 0x00, 0x34 }, + { "option", 0x00, 0x35 }, + { "refresh", 0x00, 0x36 }, + { "select", 0x00, 0x37 }, + { "setvar", 0x00, 0x3e }, /* WML 1.1 */ + { "small", 0x00, 0x38 }, + { "strong", 0x00, 0x39 }, + { "table", 0x00, 0x1f }, /* WML 1.1 */ + { "td", 0x00, 0x1d }, /* WML 1.1 */ + { "template", 0x00, 0x3b }, + { "timer", 0x00, 0x3c }, + { "tr", 0x00, 0x1e }, /* WML 1.1 */ + { "u", 0x00, 0x3d }, + { "wml", 0x00, 0x3f }, + { NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrEntry sv_wml13_attr_table[] = { + { "accept-charset", NULL, 0x00, 0x05 }, + { "accesskey", NULL, 0x00, 0x5e }, /* WML 1.2 */ + { "align", NULL, 0x00, 0x52 }, /* WML 1.1 */ + { "align", "bottom", 0x00, 0x06 }, + { "align", "center", 0x00, 0x07 }, + { "align", "left", 0x00, 0x08 }, + { "align", "middle", 0x00, 0x09 }, + { "align", "right", 0x00, 0x0a }, + { "align", "top", 0x00, 0x0b }, + { "alt", NULL, 0x00, 0x0c }, + { "cache-control", "no-cache", 0x00, 0x64 }, /* WML 1.3 */ + { "class", NULL, 0x00, 0x54 }, /* WML 1.1 */ + { "columns", NULL, 0x00, 0x53 }, /* WML 1.1 */ + { "content", NULL, 0x00, 0x0d }, + { "content", "application/vnd.wap.wmlc;charset=", 0x00, 0x5c }, /* WML 1.1 */ + { "domain", NULL, 0x00, 0x0f }, + { "emptyok", "false", 0x00, 0x10 }, + { "emptyok", "true", 0x00, 0x11 }, + { "enctype", NULL, 0x00, 0x5f }, /* WML 1.2 */ + { "enctype", "application/x-www-form-urlencoded", 0x00, 0x60 }, /* WML 1.2 */ + { "enctype", "multipart/form-data", 0x00, 0x61 }, /* WML 1.2 */ + { "format", NULL, 0x00, 0x12 }, + { "forua", "false", 0x00, 0x56 }, /* WML 1.1 */ + { "forua", "true", 0x00, 0x57 }, /* WML 1.1 */ + { "height", NULL, 0x00, 0x13 }, + { "href", NULL, 0x00, 0x4a }, /* WML 1.1 */ + { "href", "http://", 0x00, 0x4b }, /* WML 1.1 */ + { "href", "https://", 0x00, 0x4c }, /* WML 1.1 */ + { "hspace", NULL, 0x00, 0x14 }, + { "http-equiv", NULL, 0x00, 0x5a }, /* WML 1.1 */ + { "http-equiv", "Content-Type", 0x00, 0x5b }, /* WML 1.1 */ + { "http-equiv", "Expires", 0x00, 0x5d }, /* WML 1.1 */ + { "id", NULL, 0x00, 0x55 }, /* WML 1.1 */ + { "ivalue", NULL, 0x00, 0x15 }, /* WML 1.1 */ + { "iname", NULL, 0x00, 0x16 }, /* WML 1.1 */ + { "label", NULL, 0x00, 0x18 }, + { "localsrc", NULL, 0x00, 0x19 }, + { "maxlength", NULL, 0x00, 0x1a }, + { "method", "get", 0x00, 0x1b }, + { "method", "post", 0x00, 0x1c }, + { "mode", "nowrap", 0x00, 0x1d }, + { "mode", "wrap", 0x00, 0x1e }, + { "multiple", "false", 0x00, 0x1f }, + { "multiple", "true", 0x00, 0x20 }, + { "name", NULL, 0x00, 0x21 }, + { "newcontext", "false", 0x00, 0x22 }, + { "newcontext", "true", 0x00, 0x23 }, + { "onenterbackward", NULL, 0x00, 0x25 }, + { "onenterforward", NULL, 0x00, 0x26 }, + { "onpick", NULL, 0x00, 0x24 }, /* WML 1.1 */ + { "ontimer", NULL, 0x00, 0x27 }, + { "optional", "false", 0x00, 0x28 }, + { "optional", "true", 0x00, 0x29 }, + { "path", NULL, 0x00, 0x2a }, + { "scheme", NULL, 0x00, 0x2e }, + { "sendreferer", "false", 0x00, 0x2f }, + { "sendreferer", "true", 0x00, 0x30 }, + { "size", NULL, 0x00, 0x31 }, + { "src", NULL, 0x00, 0x32 }, + { "src", "http://", 0x00, 0x58 }, /* WML 1.1 */ + { "src", "https://", 0x00, 0x59 }, /* WML 1.1 */ + { "ordered", "true", 0x00, 0x33 }, /* WML 1.1 */ + { "ordered", "false", 0x00, 0x34 }, /* WML 1.1 */ + { "tabindex", NULL, 0x00, 0x35 }, + { "title", NULL, 0x00, 0x36 }, + { "type", NULL, 0x00, 0x37 }, + { "type", "accept", 0x00, 0x38 }, + { "type", "delete", 0x00, 0x39 }, + { "type", "help", 0x00, 0x3a }, + { "type", "password", 0x00, 0x3b }, + { "type", "onpick", 0x00, 0x3c }, + { "type", "onenterbackward", 0x00, 0x3d }, + { "type", "onenterforward", 0x00, 0x3e }, + { "type", "ontimer", 0x00, 0x3f }, + { "type", "options", 0x00, 0x45 }, + { "type", "prev", 0x00, 0x46 }, + { "type", "reset", 0x00, 0x47 }, + { "type", "text", 0x00, 0x48 }, + { "type", "vnd.", 0x00, 0x49 }, + { "value", NULL, 0x00, 0x4d }, + { "vspace", NULL, 0x00, 0x4e }, + { "width", NULL, 0x00, 0x4f }, + { "xml:lang", NULL, 0x00, 0x50 }, + { "xml:space", "preserve", 0x00, 0x62 }, /* WML 1.3 */ + { "xml:space", "default", 0x00, 0x63 }, /* WML 1.3 */ + { NULL, NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrValueEntry sv_wml13_attr_value_table[] = { + { ".com/", 0x00, 0x85 }, + { ".edu/", 0x00, 0x86 }, + { ".net/", 0x00, 0x87 }, + { ".org/", 0x00, 0x88 }, + { "accept", 0x00, 0x89 }, + { "bottom", 0x00, 0x8a }, + { "clear", 0x00, 0x8b }, + { "delete", 0x00, 0x8c }, + { "help", 0x00, 0x8d }, + /* Do NOT change the order in this table please ! */ + { "http://www.", 0x00, 0x8f }, + { "http://", 0x00, 0x8e }, + { "https://www.", 0x00, 0x91 }, + { "https://", 0x00, 0x90 }, + { "middle", 0x00, 0x93 }, + { "nowrap", 0x00, 0x94 }, + { "onenterbackward", 0x00, 0x96 }, + { "onenterforward", 0x00, 0x97 }, + { "onpick", 0x00, 0x95 }, /* WML 1.1 */ + { "ontimer", 0x00, 0x98 }, + { "options", 0x00, 0x99 }, + { "password", 0x00, 0x9a }, + { "reset", 0x00, 0x9b }, + { "text", 0x00, 0x9d }, + { "top", 0x00, 0x9e }, + { "unknown", 0x00, 0x9f }, + { "wrap", 0x00, 0xa0 }, + { "www.", 0x00, 0xa1 }, + { NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_SUPPORT_WML */ + + + +#if defined( WBXML_SUPPORT_WTA ) + +/******************************************** + * WTA 1.0 (WAP 1.0: "wta-30-apr-98.pdf") + */ + +const WBXMLTagEntry sv_wta10_tag_table[] = { + { "EVENT", 0x00, 0x05 }, + { "EVENTTABLE", 0x00, 0x06 }, + { "TYPE", 0x00, 0x07 }, + { "URL", 0x00, 0x08 }, + { "WTAI", 0x00, 0x09 }, + { NULL, 0x00, 0x00 } +}; + +const WBXMLAttrEntry sv_wta10_attr_table[] = { + { "NAME", NULL, 0x00, 0x05 }, + { "VALUE", NULL, 0x00, 0x06 }, + { NULL, NULL, 0x00, 0x00 } +}; + + +/*********************************************** + * WTA WML 1.2 ("WAP-266-WTA-20010908-a.pdf") + */ + +const WBXMLTagEntry sv_wtawml12_tag_table[] = { + /* Code Page 0 (WML 1.2) */ + { "a", 0x00, 0x1c }, + { "anchor", 0x00, 0x22 }, + { "access", 0x00, 0x23 }, + { "b", 0x00, 0x24 }, + { "big", 0x00, 0x25 }, + { "br", 0x00, 0x26 }, + { "card", 0x00, 0x27 }, + { "do", 0x00, 0x28 }, + { "em", 0x00, 0x29 }, + { "fieldset", 0x00, 0x2a }, + { "go", 0x00, 0x2b }, + { "head", 0x00, 0x2c }, + { "i", 0x00, 0x2d }, + { "img", 0x00, 0x2e }, + { "input", 0x00, 0x2f }, + { "meta", 0x00, 0x30 }, + { "noop", 0x00, 0x31 }, + { "p", 0x00, 0x20 }, + { "postfield", 0x00, 0x21 }, + { "pre", 0x00, 0x1b }, + { "prev", 0x00, 0x32 }, + { "onevent", 0x00, 0x33 }, + { "optgroup", 0x00, 0x34 }, + { "option", 0x00, 0x35 }, + { "refresh", 0x00, 0x36 }, + { "select", 0x00, 0x37 }, + { "setvar", 0x00, 0x3e }, + { "small", 0x00, 0x38 }, + { "strong", 0x00, 0x39 }, + { "table", 0x00, 0x1f }, + { "td", 0x00, 0x1d }, + { "template", 0x00, 0x3b }, + { "timer", 0x00, 0x3c }, + { "tr", 0x00, 0x1e }, + { "u", 0x00, 0x3d }, + { "wml", 0x00, 0x3f }, + + /* Code Page 1 (WTA) */ + { "wta-wml", 0x01, 0x3f }, + { NULL, 0x00, 0x00 } +}; + +const WBXMLAttrEntry sv_wtawml12_attr_table[] = { + /* Code Page 0 (WML 1.2) */ + { "accept-charset", NULL, 0x00, 0x05 }, + { "accesskey", NULL, 0x00, 0x5e }, + { "align", NULL, 0x00, 0x52 }, + { "align", "bottom", 0x00, 0x06 }, + { "align", "center", 0x00, 0x07 }, + { "align", "left", 0x00, 0x08 }, + { "align", "middle", 0x00, 0x09 }, + { "align", "right", 0x00, 0x0a }, + { "align", "top", 0x00, 0x0b }, + { "alt", NULL, 0x00, 0x0c }, + { "class", NULL, 0x00, 0x54 }, + { "columns", NULL, 0x00, 0x53 }, + { "content", NULL, 0x00, 0x0d }, + { "content", "application/vnd.wap.wmlc;charset=", 0x00, 0x5c }, + { "domain", NULL, 0x00, 0x0f }, + { "emptyok", "false", 0x00, 0x10 }, + { "emptyok", "true", 0x00, 0x11 }, + { "enctype", NULL, 0x00, 0x5f }, + { "enctype", "application/x-www-form-urlencoded", 0x00, 0x60 }, + { "enctype", "multipart/form-data", 0x00, 0x61 }, + { "format", NULL, 0x00, 0x12 }, + { "forua", "false", 0x00, 0x56 }, + { "forua", "true", 0x00, 0x57 }, + { "height", NULL, 0x00, 0x13 }, + { "href", NULL, 0x00, 0x4a }, + { "href", "http://", 0x00, 0x4b }, + { "href", "https://", 0x00, 0x4c }, + { "hspace", NULL, 0x00, 0x14 }, + { "http-equiv", NULL, 0x00, 0x5a }, + { "http-equiv", "Content-Type", 0x00, 0x5b }, + { "http-equiv", "Expires", 0x00, 0x5d }, + { "id", NULL, 0x00, 0x55 }, + { "ivalue", NULL, 0x00, 0x15 }, + { "iname", NULL, 0x00, 0x16 }, + { "label", NULL, 0x00, 0x18 }, + { "localsrc", NULL, 0x00, 0x19 }, + { "maxlength", NULL, 0x00, 0x1a }, + { "method", "get", 0x00, 0x1b }, + { "method", "post", 0x00, 0x1c }, + { "mode", "nowrap", 0x00, 0x1d }, + { "mode", "wrap", 0x00, 0x1e }, + { "multiple", "false", 0x00, 0x1f }, + { "multiple", "true", 0x00, 0x20 }, + { "name", NULL, 0x00, 0x21 }, + { "newcontext", "false", 0x00, 0x22 }, + { "newcontext", "true", 0x00, 0x23 }, + { "onenterbackward", NULL, 0x00, 0x25 }, + { "onenterforward", NULL, 0x00, 0x26 }, + { "onpick", NULL, 0x00, 0x24 }, + { "ontimer", NULL, 0x00, 0x27 }, + { "optional", "false", 0x00, 0x28 }, + { "optional", "true", 0x00, 0x29 }, + { "path", NULL, 0x00, 0x2a }, + { "scheme", NULL, 0x00, 0x2e }, + { "sendreferer", "false", 0x00, 0x2f }, + { "sendreferer", "true", 0x00, 0x30 }, + { "size", NULL, 0x00, 0x31 }, + { "src", NULL, 0x00, 0x32 }, + { "src", "http://", 0x00, 0x58 }, + { "src", "https://", 0x00, 0x59 }, + { "ordered", "true", 0x00, 0x33 }, + { "ordered", "false", 0x00, 0x34 }, + { "tabindex", NULL, 0x00, 0x35 }, + { "title", NULL, 0x00, 0x36 }, + { "type", NULL, 0x00, 0x37 }, + { "type", "accept", 0x00, 0x38 }, + { "type", "delete", 0x00, 0x39 }, + { "type", "help", 0x00, 0x3a }, + { "type", "password", 0x00, 0x3b }, + { "type", "onpick", 0x00, 0x3c }, + { "type", "onenterbackward", 0x00, 0x3d }, + { "type", "onenterforward", 0x00, 0x3e }, + { "type", "ontimer", 0x00, 0x3f }, + { "type", "options", 0x00, 0x45 }, + { "type", "prev", 0x00, 0x46 }, + { "type", "reset", 0x00, 0x47 }, + { "type", "text", 0x00, 0x48 }, + { "type", "vnd.", 0x00, 0x49 }, + { "value", NULL, 0x00, 0x4d }, + { "vspace", NULL, 0x00, 0x4e }, + { "width", NULL, 0x00, 0x4f }, + { "xml:lang", NULL, 0x00, 0x50 }, + + /* Code Page 1 (WTA) */ + /* Do NOT change the order in this table please ! */ + { "href", "wtai://wp/mc;", 0x01, 0x06 }, + { "href", "wtai://wp/sd;", 0x01, 0x07 }, + { "href", "wtai://wp/ap;", 0x01, 0x08 }, + { "href", "wtai://ms/ec;", 0x01, 0x09 }, + { "href", "wtai://", 0x01, 0x05 }, + { "type", "wtaev-cc/ic", 0x01, 0x12 }, + { "type", "wtaev-cc/cl", 0x01, 0x13 }, + { "type", "wtaev-cc/co", 0x01, 0x14 }, + { "type", "wtaev-cc/oc", 0x01, 0x15 }, + { "type", "wtaev-cc/cc", 0x01, 0x16 }, + { "type", "wtaev-cc/dtmf", 0x01, 0x17 }, + { "type", "wtaev-nt/it", 0x01, 0x21 }, + { "type", "wtaev-nt/st", 0x01, 0x22 }, + { "type", "wtaev-nt/", 0x01, 0x20 }, + { "type", "wtaev-pb/", 0x01, 0x30 }, + { "type", "wtaev-lg/", 0x01, 0x38 }, + { "type", "wtaev-ms/ns", 0x01, 0x51 }, + { "type", "wtaev-ms/", 0x01, 0x50 }, + { "type", "wtaev-gsm/ru", 0x01, 0x59 }, + { "type", "wtaev-gsm/ch", 0x01, 0x5a }, + { "type", "wtaev-gsm/ca", 0x01, 0x5b }, + { "type", "wtaev-gsm/", 0x01, 0x58 }, + { "type", "wtaev-pdc", 0x01, 0x60 }, + { "type", "wtaev-ansi136/ia", 0x01, 0x69 }, + { "type", "wtaev-ansi136/if", 0x01, 0x6a }, + { "type", "wtaev-ansi136", 0x01, 0x68 }, + { "type", "wtaev-cdma/", 0x01, 0x70 }, + { "type", "wtaev-cc", 0x01, 0x11 }, + { "type", "wtaev-", 0x01, 0x10 }, + { NULL, NULL, 0x00, 0x00 } +}; + +const WBXMLAttrValueEntry sv_wtawml12_attr_value_table[] = { + /* Code Page 0 (WML 1.2) */ + { ".com/", 0x00, 0x85 }, + { ".edu/", 0x00, 0x86 }, + { ".net/", 0x00, 0x87 }, + { ".org/", 0x00, 0x88 }, + { "accept", 0x00, 0x89 }, + { "bottom", 0x00, 0x8a }, + { "clear", 0x00, 0x8b }, + { "delete", 0x00, 0x8c }, + { "help", 0x00, 0x8d }, + /* Do NOT change the order in this table please ! */ + { "http://www.", 0x00, 0x8f }, + { "http://", 0x00, 0x8e }, + { "https://www.", 0x00, 0x91 }, + { "https://", 0x00, 0x90 }, + { "middle", 0x00, 0x93 }, + { "nowrap", 0x00, 0x94 }, + { "onenterbackward", 0x00, 0x96 }, + { "onenterforward", 0x00, 0x97 }, + { "onpick", 0x00, 0x95 }, + { "ontimer", 0x00, 0x98 }, + { "options", 0x00, 0x99 }, + { "password", 0x00, 0x9a }, + { "reset", 0x00, 0x9b }, + { "text", 0x00, 0x9d }, + { "top", 0x00, 0x9e }, + { "unknown", 0x00, 0x9f }, + { "wrap", 0x00, 0xa0 }, + { "www.", 0x00, 0xa1 }, + { NULL, 0x00, 0x00 } +}; + + +/*************************************************** + * CHANNEL 1.1 (WAP 1.1: "SPEC-WTA-19990716.pdf") + */ + +const WBXMLTagEntry sv_channel11_tag_table[] = { + { "channel", 0x00, 0x05 }, + { "title", 0x00, 0x06 }, + { "abstract", 0x00, 0x07 }, + { "resource", 0x00, 0x08 }, + { NULL, 0x00, 0x00 } +}; + +const WBXMLAttrEntry sv_channel11_attr_table[] = { + { "maxspace", NULL, 0x00, 0x05 }, + { "base", NULL, 0x00, 0x06 }, + { "href", NULL, 0x00, 0x07 }, + { "href", "http://", 0x00, 0x08 }, + { "href", "https://", 0x00, 0x09 }, + { "lastmod", NULL, 0x00, 0x0a }, + { "etag", NULL, 0x00, 0x0b }, + { "md5", NULL, 0x00, 0x0c }, + { "success", NULL, 0x00, 0x0d }, + { "success", "http://", 0x00, 0x0e }, + { "success", "https://", 0x00, 0x0f }, + { "failure", NULL, 0x00, 0x10 }, + { "failure", "http://", 0x00, 0x11 }, + { "failure", "https://", 0x00, 0x12 }, + { "EventId", NULL, 0x00, 0x13 }, + { NULL, NULL, 0x00, 0x00 } +}; + + +/*********************************************** + * CHANNEL 1.2 ("WAP-266-WTA-20010908-a.pdf") + */ + +const WBXMLTagEntry sv_channel12_tag_table[] = { + { "channel", 0x00, 0x05 }, + { "title", 0x00, 0x06 }, + { "abstract", 0x00, 0x07 }, + { "resource", 0x00, 0x08 }, + { NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrEntry sv_channel12_attr_table[] = { + { "maxspace", NULL, 0x00, 0x05 }, + { "base", NULL, 0x00, 0x06 }, + { "href", NULL, 0x00, 0x07 }, + { "href", "http://", 0x00, 0x08 }, + { "href", "https://", 0x00, 0x09 }, + { "lastmod", NULL, 0x00, 0x0a }, + { "etag", NULL, 0x00, 0x0b }, + { "md5", NULL, 0x00, 0x0c }, + { "success", NULL, 0x00, 0x0d }, + { "success", "http://", 0x00, 0x0e }, + { "success", "https://", 0x00, 0x0f }, + { "failure", NULL, 0x00, 0x10 }, + { "failure", "http://", 0x00, 0x11 }, + { "failure", "https://", 0x00, 0x12 }, + { "eventid", NULL, 0x00, 0x13 }, + { "eventid", "wtaev-", 0x00, 0x14 }, + { "channelid", NULL, 0x00, 0x15 }, + { "useraccessible", NULL, 0x00, 0x16 }, + { NULL, NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_SUPPORT_WTA */ + + +#if defined( WBXML_SUPPORT_SI ) + +/************************************************* + * SI 1.0 ("WAP-167-ServiceInd-20010731-a.pdf") + */ + +const WBXMLTagEntry sv_si10_tag_table[] = { + { "si", 0x00, 0x05 }, + { "indication", 0x00, 0x06 }, + { "info", 0x00, 0x07 }, + { "item", 0x00, 0x08 }, + { NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrEntry sv_si10_attr_table[] = { + { "action", "signal-none", 0x00, 0x05 }, + { "action", "signal-low", 0x00, 0x06 }, + { "action", "signal-medium", 0x00, 0x07 }, + { "action", "signal-high", 0x00, 0x08 }, + { "action", "delete", 0x00, 0x09 }, + { "created", NULL, 0x00, 0x0a }, + { "href", NULL, 0x00, 0x0b }, + /* Do NOT change the order in this table please ! */ + { "href", "http://www.", 0x00, 0x0d }, + { "href", "http://", 0x00, 0x0c }, + { "href", "https://www.", 0x00, 0x0f }, + { "href", "https://", 0x00, 0x0e }, + { "si-expires", NULL, 0x00, 0x10 }, + { "si-id", NULL, 0x00, 0x11 }, + { "class", NULL, 0x00, 0x12 }, + { NULL, NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrValueEntry sv_si10_attr_value_table[] = { + { ".com/", 0x00, 0x85 }, + { ".edu/", 0x00, 0x86 }, + { ".net/", 0x00, 0x87 }, + { ".org/", 0x00, 0x88 }, + { NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_SUPPORT_SI */ + + +#if defined( WBXML_SUPPORT_SL ) + +/************************************************** + * SL 1.0 ("WAP-168-ServiceLoad-20010731-a.pdf") + */ + +const WBXMLTagEntry sv_sl10_tag_table[] = { + { "sl", 0x00, 0x05 }, + { NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrEntry sv_sl10_attr_table[] = { + { "action", "execute-low", 0x00, 0x05 }, + { "action", "execute-high", 0x00, 0x06 }, + { "action", "cache", 0x00, 0x07 }, + { "href", NULL, 0x00, 0x08 }, + /* Do NOT change the order in this table please ! */ + { "href", "http://www.", 0x00, 0x0a }, + { "href", "http://", 0x00, 0x09 }, + { "href", "https://www.", 0x00, 0x0c }, + { "href", "https://", 0x00, 0x0b }, + { NULL, NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrValueEntry sv_sl10_attr_value_table[] = { + { ".com/", 0x00, 0x85 }, + { ".edu/", 0x00, 0x86 }, + { ".net/", 0x00, 0x87 }, + { ".org/", 0x00, 0x88 }, + { NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_SUPPORT_SL */ + + +#if defined( WBXML_SUPPORT_CO ) + +/*********************************************** + * CO 1.0 ("WAP-175-CacheOp-20010731-a.pdf") + */ + +const WBXMLTagEntry sv_co10_tag_table[] = { + { "co", 0x00, 0x05 }, + { "invalidate-object", 0x00, 0x06 }, + { "invalidate-service", 0x00, 0x07 }, + { NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrEntry sv_co10_attr_table[] = { + { "uri", NULL, 0x00, 0x05 }, + /* Do NOT change the order in this table please ! */ + { "uri", "http://www.", 0x00, 0x07 }, + { "uri", "http://", 0x00, 0x06 }, + { "uri", "https://www.", 0x00, 0x09 }, + { "uri", "https://", 0x00, 0x08 }, + { NULL, NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrValueEntry sv_co10_attr_value_table[] = { + { ".com/", 0x00, 0x85 }, + { ".edu/", 0x00, 0x86 }, + { ".net/", 0x00, 0x87 }, + { ".org/", 0x00, 0x88 }, + { NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_SUPPORT_CO */ + + +#if defined( WBXML_SUPPORT_PROV ) + +/** Use OMA PROV 1.1 Tables (only 'sv_prov10_attr_value_table' changed) */ +#define WBXML_SUPPORT_PROV_11 + +/********************************************************** + * PROV 1.0 + * WAP 2.0: "WAP-183-PROVCONT-20010724-a.pdf" + * OMA: "OMA-WAP-ProvCont-v1_1-20021112-C.PDF" + * + * PROV 1.1 + * OMA: OMA-WAP-ProvCont-v1_1-20050428-Cchangebars.doc + * There is no new Public ID defined for this new version, + * so how should we handle this ?? + */ + +const WBXMLTagEntry sv_prov10_tag_table[] = { + { "wap-provisioningdoc", 0x00, 0x05 }, + { "characteristic", 0x00, 0x06 }, + { "parm", 0x00, 0x07 }, + + { "characteristic", 0x01, 0x06 }, /* OMA */ + { "parm", 0x01, 0x07 }, /* OMA */ + { NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrEntry sv_prov10_attr_table[] = { + /* Wap-provisioningdoc */ + { "version", NULL, 0x00, 0x45 }, + { "version", "1.0", 0x00, 0x46 }, + + /* Characteristic */ + { "type", NULL, 0x00, 0x50 }, + { "type", "PXLOGICAL", 0x00, 0x51 }, + { "type", "PXPHYSICAL", 0x00, 0x52 }, + { "type", "PORT", 0x00, 0x53 }, + { "type", "VALIDITY", 0x00, 0x54 }, + { "type", "NAPDEF", 0x00, 0x55 }, + { "type", "BOOTSTRAP", 0x00, 0x56 }, + { "type", "VENDORCONFIG", 0x00, 0x57 }, + { "type", "CLIENTIDENTITY", 0x00, 0x58 }, + { "type", "PXAUTHINFO", 0x00, 0x59 }, + { "type", "NAPAUTHINFO", 0x00, 0x5a }, + { "type", "ACCESS", 0x00, 0x5b }, /* OMA */ + + { "type", NULL, 0x01, 0x50 }, /* OMA */ + { "type", "PORT", 0x01, 0x53 }, /* OMA */ + { "type", "CLIENTIDENTITY", 0x01, 0x58 }, /* OMA */ + { "type", "APPLICATION", 0x01, 0x55 }, /* OMA */ + { "type", "APPADDR", 0x01, 0x56 }, /* OMA */ + { "type", "APPAUTH", 0x01, 0x57 }, /* OMA */ + { "type", "RESOURCE", 0x01, 0x59 }, /* OMA */ + + /* Parm */ + { "name", NULL, 0x00, 0x05 }, + { "value", NULL, 0x00, 0x06 }, + { "name", "NAME", 0x00, 0x07 }, + { "name", "NAP-ADDRESS", 0x00, 0x08 }, + { "name", "NAP-ADDRTYPE", 0x00, 0x09 }, + { "name", "CALLTYPE", 0x00, 0x0a }, + { "name", "VALIDUNTIL", 0x00, 0x0b }, + { "name", "AUTHTYPE", 0x00, 0x0c }, + { "name", "AUTHNAME", 0x00, 0x0d }, + { "name", "AUTHSECRET", 0x00, 0x0e }, + { "name", "LINGER", 0x00, 0x0f }, + { "name", "BEARER", 0x00, 0x10 }, + { "name", "NAPID", 0x00, 0x11 }, + { "name", "COUNTRY", 0x00, 0x12 }, + { "name", "NETWORK", 0x00, 0x13 }, + { "name", "INTERNET", 0x00, 0x14 }, + { "name", "PROXY-ID", 0x00, 0x15 }, + { "name", "PROXY-PROVIDER-ID", 0x00, 0x16 }, + { "name", "DOMAIN", 0x00, 0x17 }, + { "name", "PROVURL", 0x00, 0x18 }, + { "name", "PXAUTH-TYPE", 0x00, 0x19 }, + { "name", "PXAUTH-ID", 0x00, 0x1a }, + { "name", "PXAUTH-PW", 0x00, 0x1b }, + { "name", "STARTPAGE", 0x00, 0x1c }, + { "name", "BASAUTH-ID", 0x00, 0x1d }, + { "name", "BASAUTH-PW", 0x00, 0x1e }, + { "name", "PUSHENABLED", 0x00, 0x1f }, + { "name", "PXADDR", 0x00, 0x20 }, + { "name", "PXADDRTYPE", 0x00, 0x21 }, + { "name", "TO-NAPID", 0x00, 0x22 }, + { "name", "PORTNBR", 0x00, 0x23 }, + { "name", "SERVICE", 0x00, 0x24 }, + { "name", "LINKSPEED", 0x00, 0x25 }, + { "name", "DNLINKSPEED", 0x00, 0x26 }, + { "name", "LOCAL-ADDR", 0x00, 0x27 }, + { "name", "LOCAL-ADDRTYPE", 0x00, 0x28 }, + { "name", "CONTEXT-ALLOW", 0x00, 0x29 }, + { "name", "TRUST", 0x00, 0x2a }, + { "name", "MASTER", 0x00, 0x2b }, + { "name", "SID", 0x00, 0x2c }, + { "name", "SOC", 0x00, 0x2d }, + { "name", "WSP-VERSION", 0x00, 0x2e }, + { "name", "PHYSICAL-PROXY-ID", 0x00, 0x2f }, + { "name", "CLIENT-ID", 0x00, 0x30 }, + { "name", "DELIVERY-ERR-SDU", 0x00, 0x31 }, + { "name", "DELIVERY-ORDER", 0x00, 0x32 }, + { "name", "TRAFFIC-CLASS", 0x00, 0x33 }, + { "name", "MAX-SDU-SIZE", 0x00, 0x34 }, + { "name", "MAX-BITRATE-UPLINK", 0x00, 0x35 }, + { "name", "MAX-BITRATE-DNLINK", 0x00, 0x36 }, + { "name", "RESIDUAL-BER", 0x00, 0x37 }, + { "name", "SDU-ERROR-RATIO", 0x00, 0x38 }, + { "name", "TRAFFIC-HANDL-PRIO", 0x00, 0x39 }, + { "name", "TRANSFER-DELAY", 0x00, 0x3a }, + { "name", "GUARANTEED-BITRATE-UPLINK", 0x00, 0x3b }, + { "name", "GUARANTEED-BITRATE-DNLINK", 0x00, 0x3c }, + { "name", "PXADDR-FQDN", 0x00, 0x3d }, /* OMA */ + { "name", "PROXY-PW", 0x00, 0x3e }, /* OMA */ + { "name", "PPGAUTH-TYPE", 0x00, 0x3f }, /* OMA */ + { "name", "PULLENABLED", 0x00, 0x47 }, /* OMA */ + { "name", "DNS-ADDR", 0x00, 0x48 }, /* OMA */ + { "name", "MAX-NUM-RETRY", 0x00, 0x49 }, /* OMA */ + { "name", "FIRST-RETRY-TIMEOUT", 0x00, 0x4a }, /* OMA */ + { "name", "REREG-THRESHOLD", 0x00, 0x4b }, /* OMA */ + { "name", "T-BIT", 0x00, 0x4c }, /* OMA */ + { "name", "AUTH-ENTITY", 0x00, 0x4e }, /* OMA */ + { "name", "SPI", 0x00, 0x4f }, /* OMA */ + + { "name", NULL, 0x01, 0x05 }, /* OMA */ + { "value", NULL, 0x01, 0x06 }, /* OMA */ + { "name", "NAME", 0x01, 0x07 }, /* OMA */ + { "name", "INTERNET", 0x01, 0x14 }, /* OMA */ + { "name", "STARTPAGE", 0x01, 0x1c }, /* OMA */ + { "name", "TO-NAPID", 0x01, 0x22 }, /* OMA */ + { "name", "PORTNBR", 0x01, 0x23 }, /* OMA */ + { "name", "SERVICE", 0x01, 0x24 }, /* OMA */ + { "name", "AACCEPT", 0x01, 0x2e }, /* OMA */ + { "name", "AAUTHDATA", 0x01, 0x2f }, /* OMA */ + { "name", "AAUTHLEVEL", 0x01, 0x30 }, /* OMA */ + { "name", "AAUTHNAME", 0x01, 0x31 }, /* OMA */ + { "name", "AAUTHSECRET", 0x01, 0x32 }, /* OMA */ + { "name", "AAUTHTYPE", 0x01, 0x33 }, /* OMA */ + { "name", "ADDR", 0x01, 0x34 }, /* OMA */ + { "name", "ADDRTYPE", 0x01, 0x35 }, /* OMA */ + { "name", "APPID", 0x01, 0x36 }, /* OMA */ + { "name", "APROTOCOL", 0x01, 0x37 }, /* OMA */ + { "name", "PROVIDER-ID", 0x01, 0x38 }, /* OMA */ + { "name", "TO-PROXY", 0x01, 0x39 }, /* OMA */ + { "name", "URI", 0x01, 0x3a }, /* OMA */ + { "name", "RULE", 0x01, 0x3b }, /* OMA */ + + { NULL, NULL, 0x00, 0x00 } +}; + + +const WBXMLAttrValueEntry sv_prov10_attr_value_table[] = { + /* ADDRTYPE */ + { "IPV4", 0x00, 0x85 }, + { "IPV6", 0x00, 0x86 }, + { "E164", 0x00, 0x87 }, + { "ALPHA", 0x00, 0x88 }, + { "APN", 0x00, 0x89 }, + { "SCODE", 0x00, 0x8a }, + { "TETRA-ITSI", 0x00, 0x8b }, + { "MAN", 0x00, 0x8c }, + + { "IPV6", 0x01, 0x86 }, /* OMA */ + { "E164", 0x01, 0x87 }, /* OMA */ + { "ALPHA", 0x01, 0x88 }, /* OMA */ + { "APPSRV", 0x01, 0x8d }, /* OMA */ + { "OBEX", 0x01, 0x8e }, /* OMA */ + + /* CALLTYPE */ + { "ANALOG-MODEM", 0x00, 0x90 }, + { "V.120", 0x00, 0x91 }, + { "V.110", 0x00, 0x92 }, + { "X.31", 0x00, 0x93 }, + { "BIT-TRANSPARENT", 0x00, 0x94 }, + { "DIRECT-ASYNCHRONOUS-DATA-SERVICE", 0x00, 0x95 }, + + /* AUTHTYPE/PXAUTH-TYPE */ + { "PAP", 0x00, 0x9a }, + { "CHAP", 0x00, 0x9b }, + { "HTTP-BASIC", 0x00, 0x9c }, + { "HTTP-DIGEST", 0x00, 0x9d }, + { "WTLS-SS", 0x00, 0x9e }, + { "MD5", 0x00, 0x9f }, /* OMA */ + + /* BEARER */ + { "GSM-USSD", 0x00, 0xa2 }, + { "GSM-SMS", 0x00, 0xa3 }, + { "ANSI-136-GUTS", 0x00, 0xa4 }, + { "IS-95-CDMA-SMS", 0x00, 0xa5 }, + { "IS-95-CDMA-CSD", 0x00, 0xa6 }, + { "IS-95-CDMA-PACKET", 0x00, 0xa7 }, + { "ANSI-136-CSD", 0x00, 0xa8 }, + { "ANSI-136-GPRS", 0x00, 0xa9 }, + { "GSM-CSD", 0x00, 0xaa }, + { "GSM-GPRS", 0x00, 0xab }, + { "AMPS-CDPD", 0x00, 0xac }, + { "PDC-CSD", 0x00, 0xad }, + { "PDC-PACKET", 0x00, 0xae }, + { "IDEN-SMS", 0x00, 0xaf }, + { "IDEN-CSD", 0x00, 0xb0 }, + { "IDEN-PACKET", 0x00, 0xb1 }, + { "FLEX/REFLEX", 0x00, 0xb2 }, + { "PHS-SMS", 0x00, 0xb3 }, + { "PHS-CSD", 0x00, 0xb4 }, + { "TRETRA-SDS", 0x00, 0xb5 }, + { "TRETRA-PACKET", 0x00, 0xb6 }, + { "ANSI-136-GHOST", 0x00, 0xb7 }, + { "MOBITEX-MPAK", 0x00, 0xb8 }, + { "CDMA2000-1X-SIMPLE-IP", 0x00, 0xb9 }, /* OMA */ + { "CDMA2000-1X-MOBILE-IP", 0x00, 0xba }, /* OMA */ + + /* LINKSPEED */ + { "AUTOBAUDING", 0x00, 0xc5 }, + + /* SERVICE */ + { "CL-WSP", 0x00, 0xca }, + { "CO-WSP", 0x00, 0xcb }, + { "CL-SEC-WSP", 0x00, 0xcc }, + { "CO-SEC-WSP", 0x00, 0xcd }, + { "CL-SEC-WTA", 0x00, 0xce }, + { "CO-SEC-WTA", 0x00, 0xcf }, + { "OTA-HTTP-TO", 0x00, 0xd0 }, /* OMA */ + { "OTA-HTTP-TLS-TO", 0x00, 0xd1 }, /* OMA */ + { "OTA-HTTP-PO", 0x00, 0xd2 }, /* OMA */ + { "OTA-HTTP-TLS-PO", 0x00, 0xd3 }, /* OMA */ + + /* AAUTHTYPE */ +#if defined( WBXML_SUPPORT_PROV_11 ) + + { ",", 0x01, 0x90 }, /* OMA */ + { "HTTP-", 0x01, 0x91 }, /* OMA */ + { "BASIC", 0x01, 0x92 }, /* OMA */ + { "DIGEST", 0x01, 0x93 }, /* OMA */ + +#else + + { ",", 0x01, 0x80 }, /* OMA */ + { "HTTP-", 0x01, 0x81 }, /* OMA */ + { "BASIC", 0x01, 0x82 }, /* OMA */ + { "DIGEST", 0x01, 0x83 }, /* OMA */ + +#endif /* WBXML_SUPPORT_PROV_11 */ + + /* AUTH-ENTITY */ + { "AAA", 0x00, 0xe0 }, /* OMA */ + { "HA", 0x00, 0xe1 }, /* OMA */ + + { NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_SUPPORT_PROV */ + + +#if defined( WBXML_SUPPORT_EMN ) + +/************************************************* + * Email Notification 1.0 ("OMA-Push-EMN-v1_0-20020830-C.PDF") + */ + +const WBXMLTagEntry sv_emn10_tag_table[] = { + { "emn", 0x00, 0x05 }, + { NULL, 0x00, 0x00 } +}; + +const WBXMLAttrEntry sv_emn10_attr_table[] = { + { "timestamp", NULL, 0x00, 0x05 }, + { "mailbox", NULL, 0x00, 0x06 }, + { "mailbox", "mailat:", 0x00, 0x07 }, + { "mailbox", "pop://", 0x00, 0x08 }, + { "mailbox", "imap://", 0x00, 0x09 }, + /* Do NOT change the order in this table please ! */ + { "mailbox", "http://www.", 0x00, 0x0b }, + { "mailbox", "http://", 0x00, 0x0a }, + { "mailbox", "https://www.", 0x00, 0x0d }, + { "mailbox", "https://", 0x00, 0x0c }, + { NULL, NULL, 0x00, 0x00 } +}; + +const WBXMLAttrValueEntry sv_emn10_attr_value_table[] = { + { ".com", 0x00, 0x85 }, + { ".edu", 0x00, 0x86 }, + { ".net", 0x00, 0x87 }, + { ".org", 0x00, 0x88 }, + { NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_SUPPORT_EMN */ + + +#if defined( WBXML_SUPPORT_DRMREL ) + +/************************************************* + * Rights Expression Language Version 1.0 ("OMA-Download-DRMREL-v1_0-20020913-a.pdf") + */ + +const WBXMLTagEntry sv_drmrel10_tag_table[] = { + { "o-ex:rights", 0x00, 0x05 }, + { "o-ex:context", 0x00, 0x06 }, + { "o-dd:version", 0x00, 0x07 }, + { "o-dd:uid", 0x00, 0x08 }, + { "o-ex:agreement", 0x00, 0x09 }, + { "o-ex:asset", 0x00, 0x0A }, + { "ds:KeyInfo", 0x00, 0x0B }, + { "ds:KeyValue", 0x00, 0x0C }, + { "o-ex:permission",0x00, 0x0D }, + { "o-dd:play", 0x00, 0x0E }, + { "o-dd:display", 0x00, 0x0F }, + { "o-dd:execute", 0x00, 0x10 }, + { "o-dd:print", 0x00, 0x11 }, + { "o-ex:constraint",0x00, 0x12 }, + { "o-dd:count", 0x00, 0x13 }, + { "o-dd:datetime", 0x00, 0x14 }, + { "o-dd:start", 0x00, 0x15 }, + { "o-dd:end", 0x00, 0x16 }, + { "o-dd:interval", 0x00, 0x17 }, + { NULL, 0x00, 0x00 } +}; + +const WBXMLAttrEntry sv_drmrel10_attr_table[] = { + { "xmlns:o-ex", NULL, 0x00, 0x05 }, + { "xmlns:o-dd", NULL, 0x00, 0x06 }, + { "xmlns:ds", NULL, 0x00, 0x07 }, + { NULL, NULL, 0x00, 0x00 } +}; + +const WBXMLAttrValueEntry sv_drmrel10_attr_value_table[] = { + { "http://odrl.net/1.1/ODRL-EX", 0x00, 0x85 }, + { "http://odrl.net/1.1/ODRL-DD", 0x00, 0x86 }, + { "http://www.w3.org/2000/09/xmldsig#/",0x00, 0x87 }, + { NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_SUPPORT_DRMREL */ + + +#if defined( WBXML_SUPPORT_OTA_SETTINGS ) + +/******************************************************************** + * Ericsson / Nokia OTA Settings ("OTA_settings_general_7_0.pdf") + */ + +const WBXMLTagEntry sv_ota_settings_tag_table[] = { + { "CHARACTERISTIC-LIST", 0x00, 0x05 }, + { "CHARACTERISTIC", 0x00, 0x06 }, + { "PARM", 0x00, 0x07 }, + + { NULL, 0x00, 0x00 } +}; + +const WBXMLAttrEntry sv_ota_settings_attr_table[] = { + /* Characteristic */ + { "TYPE", "ADDRESS", 0x00, 0x06 }, + { "TYPE", "URL", 0x00, 0x07 }, + { "TYPE", "NAME", 0x00, 0x08 }, + { "NAME", NULL, 0x00, 0x10 }, + { "VALUE", NULL, 0x00, 0x11 }, + { "NAME", "BEARER", 0x00, 0x12 }, + { "NAME", "PROXY", 0x00, 0x13 }, + { "NAME", "PORT", 0x00, 0x14 }, + { "NAME", "NAME", 0x00, 0x15 }, + { "NAME", "PROXY_TYPE", 0x00, 0x16 }, + { "NAME", "URL", 0x00, 0x17 }, + { "NAME", "PROXY_AUTHNAME", 0x00, 0x18 }, + { "NAME", "PROXY_AUTHSECRET", 0x00, 0x19 }, + { "NAME", "SMS_SMSC_ADDRESS", 0x00, 0x1A }, + { "NAME", "USSD_SERVICE_CODE", 0x00, 0x1B }, + { "NAME", "GPRS_ACCESSPOINTNAME",0x00, 0x1C }, + { "NAME", "PPP_LOGINTYPE", 0x00, 0x1D }, + { "NAME", "PROXY_LOGINTYPE", 0x00, 0x1E }, + { "NAME", "CSD_DIALSTRING", 0x00, 0x21 }, + { "NAME", "CSD_CALLTYPE", 0x00, 0x28 }, + { "NAME", "CSD_CALLSPEED", 0x00, 0x29 }, + { "NAME", "PPP_AUTHTYPE", 0x00, 0x22 }, + { "NAME", "PPP_AUTHNAME", 0x00, 0x23 }, + { "NAME", "PPP_AUTHSECRET", 0x00, 0x24 }, + { "VALUE", "GSM/CSD", 0x00, 0x45 }, + { "VALUE", "GSM/SMS", 0x00, 0x46 }, + { "VALUE", "GSM/USSD", 0x00, 0x47 }, + { "VALUE", "IS-136/CSD", 0x00, 0x48 }, + { "VALUE", "GPRS", 0x00, 0x49 }, + { "VALUE", "9200", 0x00, 0x60 }, + { "VALUE", "9201", 0x00, 0x61 }, + { "VALUE", "9202", 0x00, 0x62 }, + { "VALUE", "9203", 0x00, 0x63 }, + { "VALUE", "AUTOMATIC", 0x00, 0x64 }, + { "VALUE", "MANUAL", 0x00, 0x65 }, + { "VALUE", "AUTO", 0x00, 0x6A }, + { "VALUE", "9600", 0x00, 0x6B }, + { "VALUE", "14400", 0x00, 0x6C }, + { "VALUE", "19200", 0x00, 0x6D }, + { "VALUE", "28800", 0x00, 0x6E }, + { "VALUE", "38400", 0x00, 0x6F }, + { "VALUE", "PAP", 0x00, 0x70 }, + { "VALUE", "CHAP", 0x00, 0x71 }, + { "VALUE", "ANALOGUE", 0x00, 0x72 }, + { "VALUE", "ISDN", 0x00, 0x73 }, + { "VALUE", "43200", 0x00, 0x74 }, + { "VALUE", "57600", 0x00, 0x75 }, + { "VALUE", "MSISDN_NO", 0x00, 0x76 }, + { "VALUE", "IPV4", 0x00, 0x77 }, + { "VALUE", "MS_CHAP", 0x00, 0x78 }, + { "TYPE", "MMSURL", 0x00, 0x7C }, + { "TYPE", "ID", 0x00, 0x7D }, + { "NAME", "ISP_NAME", 0x00, 0x7E }, + { "TYPE", "BOOKMARK", 0x00, 0x7F }, + + { NULL, NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_SUPPORT_OTA_SETTINGS */ + + +#if defined( WBXML_SUPPORT_SYNCML ) + +const WBXMLNameSpaceEntry sv_syncml_syncml10_ns_table[] = { + { "SYNCML:SYNCML1.0", 0x00 }, /**< Code Page 0: SYNCML1.0 */ + { "syncml:metinf", 0x01 }, /**< Code Page 1: metinf */ + { NULL, 0x00 } +}; + + +const WBXMLNameSpaceEntry sv_syncml_syncml11_ns_table[] = { + { "SYNCML:SYNCML1.1", 0x00 }, /**< Code Page 0: SYNCML1.1 */ + { "syncml:metinf", 0x01 }, /**< Code Page 1: metinf */ + { NULL, 0x00 } +}; + + +const WBXMLNameSpaceEntry sv_syncml_syncml12_ns_table[] = { + { "SYNCML:SYNCML1.2", 0x00 }, /**< Code Page 0: SYNCML1.2 */ + { "syncml:metinf", 0x01 }, /**< Code Page 1: metinf */ + { NULL, 0x00 } +}; + + +/****************************************************** + * SyncML 1.1 ("syncml_represent_v11_20020215.pdf") + */ + +const WBXMLTagEntry sv_syncml_syncml11_tag_table[] = { + /* Code Page 0: SyncML */ + { "Add", 0x00, 0x05 }, + { "Alert", 0x00, 0x06 }, + { "Archive", 0x00, 0x07 }, + { "Atomic", 0x00, 0x08 }, + { "Chal", 0x00, 0x09 }, + { "Cmd", 0x00, 0x0a }, + { "CmdID", 0x00, 0x0b }, + { "CmdRef", 0x00, 0x0c }, + { "Copy", 0x00, 0x0d }, + { "Cred", 0x00, 0x0e }, + { "Data", 0x00, 0x0f }, + { "Delete", 0x00, 0x10 }, + { "Exec", 0x00, 0x11 }, + { "Final", 0x00, 0x12 }, + { "Get", 0x00, 0x13 }, + { "Item", 0x00, 0x14 }, + { "Lang", 0x00, 0x15 }, + { "LocName", 0x00, 0x16 }, + { "LocURI", 0x00, 0x17 }, + { "Map", 0x00, 0x18 }, + { "MapItem", 0x00, 0x19 }, + { "Meta", 0x00, 0x1a }, + { "MsgID", 0x00, 0x1b }, + { "MsgRef", 0x00, 0x1c }, + { "NoResp", 0x00, 0x1d }, + { "NoResults", 0x00, 0x1e }, + { "Put", 0x00, 0x1f }, + { "Replace", 0x00, 0x20 }, + { "RespURI", 0x00, 0x21 }, + { "Results", 0x00, 0x22 }, + { "Search", 0x00, 0x23 }, + { "Sequence", 0x00, 0x24 }, + { "SessionID", 0x00, 0x25 }, + { "SftDel", 0x00, 0x26 }, + { "Source", 0x00, 0x27 }, + { "SourceRef", 0x00, 0x28 }, + { "Status", 0x00, 0x29 }, + { "Sync", 0x00, 0x2a }, + { "SyncBody", 0x00, 0x2b }, + { "SyncHdr", 0x00, 0x2c }, + { "SyncML", 0x00, 0x2d }, + { "Target", 0x00, 0x2e }, + { "TargetRef", 0x00, 0x2f }, + { "Reserved for future use", 0x00, 0x30 }, + { "VerDTD", 0x00, 0x31 }, + { "VerProto", 0x00, 0x32 }, + { "NumberOfChanges",0x00, 0x33 }, + { "MoreData", 0x00, 0x34 }, + + /* SourceParent is officially only specified for SyncML 1.2. + * Nevertheless Nokia uses this tag during the synchronization + * of SMS. So this is a proprietary extension to avoid that + * there is a tag called "unknown". + */ + { "SourceParent", 0x00, 0x39 }, + + /* Code Page 1: MetInf11 */ + { "Anchor", 0x01, 0x05 }, + { "EMI", 0x01, 0x06 }, + { "Format", 0x01, 0x07 }, + { "FreeID", 0x01, 0x08 }, + { "FreeMem", 0x01, 0x09 }, + { "Last", 0x01, 0x0a }, + { "Mark", 0x01, 0x0b }, + { "MaxMsgSize", 0x01, 0x0c }, + { "Mem", 0x01, 0x0d }, + { "MetInf", 0x01, 0x0e }, + { "Next", 0x01, 0x0f }, + { "NextNonce", 0x01, 0x10 }, + { "SharedMem", 0x01, 0x11 }, + { "Size", 0x01, 0x12 }, + { "Type", 0x01, 0x13 }, + { "Version", 0x01, 0x14 }, + { "MaxObjSize", 0x01, 0x15 }, + { NULL, 0x00, 0x00 } +}; + + +/********************************************************* + * SyncML DevInf 1.1 ("syncml_devinf_v11_20020215.pdf") + */ + +const WBXMLTagEntry sv_syncml_devinf11_tag_table[] = { + { "CTCap", 0x00, 0x05 }, + { "CTType", 0x00, 0x06 }, + { "DataStore", 0x00, 0x07 }, + { "DataType", 0x00, 0x08 }, + { "DevID", 0x00, 0x09 }, + { "DevInf", 0x00, 0x0a }, + { "DevTyp", 0x00, 0x0b }, + { "DisplayName", 0x00, 0x0c }, + { "DSMem", 0x00, 0x0d }, + { "Ext", 0x00, 0x0e }, + { "FwV", 0x00, 0x0f }, + { "HwV", 0x00, 0x10 }, + { "Man", 0x00, 0x11 }, + { "MaxGUIDSize", 0x00, 0x12 }, + { "MaxID", 0x00, 0x13 }, + { "MaxMem", 0x00, 0x14 }, + { "Mod", 0x00, 0x15 }, + { "OEM", 0x00, 0x16 }, + { "ParamName", 0x00, 0x17 }, + { "PropName", 0x00, 0x18 }, + { "Rx", 0x00, 0x19 }, + { "Rx-Pref", 0x00, 0x1a }, + { "SharedMem", 0x00, 0x1b }, + { "Size", 0x00, 0x1c }, + { "SourceRef", 0x00, 0x1d }, + { "SwV", 0x00, 0x1e }, + { "SyncCap", 0x00, 0x1f }, + { "SyncType", 0x00, 0x20 }, + { "Tx", 0x00, 0x21 }, + { "Tx-Pref", 0x00, 0x22 }, + { "ValEnum", 0x00, 0x23 }, + { "VerCT", 0x00, 0x24 }, + { "VerDTD", 0x00, 0x25 }, + { "XNam", 0x00, 0x26 }, + { "XVal", 0x00, 0x27 }, + { "UTC", 0x00, 0x28 }, + { "SupportNumberOfChanges", 0x00, 0x29 }, + { "SupportLargeObjs", 0x00, 0x2a }, + { NULL, 0x00, 0x00 } +}; + + +const WBXMLNameSpaceEntry sv_syncml_devinf11_ns_table[] = { + { "syncml:devinf", 0x00 }, /**< Code Page 0: devinf */ + { NULL, 0x00 } +}; + + +/********************************************************* + * SyncML MetInf 1.1 ("syncml_metinf_v11_20020215.pdf") + */ + +const WBXMLTagEntry sv_syncml_metinf11_tag_table[] = { + { "Anchor", 0x01, 0x05 }, + { "EMI", 0x01, 0x06 }, + { "Format", 0x01, 0x07 }, + { "FreeID", 0x01, 0x08 }, + { "FreeMem", 0x01, 0x09 }, + { "Last", 0x01, 0x0a }, + { "Mark", 0x01, 0x0b }, + { "MaxMsgSize", 0x01, 0x0c }, + { "Mem", 0x01, 0x0d }, + { "MetInf", 0x01, 0x0e }, + { "Next", 0x01, 0x0f }, + { "NextNonce", 0x01, 0x10 }, + { "SharedMem", 0x01, 0x11 }, + { "Size", 0x01, 0x12 }, + { "Type", 0x01, 0x13 }, + { "Version", 0x01, 0x14 }, + { "MaxObjSize", 0x01, 0x15 }, + { NULL, 0x00, 0x00 } +}; + + +/****************************************************** + * SyncML 1.2 ("OMA-TS-SyncML_RepPro-V1_2-20050509-C.pdf") + */ + +const WBXMLTagEntry sv_syncml_syncml12_tag_table[] = { + /* Code Page 0: SyncML */ + { "Add", 0x00, 0x05 }, + { "Alert", 0x00, 0x06 }, + { "Archive", 0x00, 0x07 }, + { "Atomic", 0x00, 0x08 }, + { "Chal", 0x00, 0x09 }, + { "Cmd", 0x00, 0x0a }, + { "CmdID", 0x00, 0x0b }, + { "CmdRef", 0x00, 0x0c }, + { "Copy", 0x00, 0x0d }, + { "Cred", 0x00, 0x0e }, + { "Data", 0x00, 0x0f }, + { "Delete", 0x00, 0x10 }, + { "Exec", 0x00, 0x11 }, + { "Final", 0x00, 0x12 }, + { "Get", 0x00, 0x13 }, + { "Item", 0x00, 0x14 }, + { "Lang", 0x00, 0x15 }, + { "LocName", 0x00, 0x16 }, + { "LocURI", 0x00, 0x17 }, + { "Map", 0x00, 0x18 }, + { "MapItem", 0x00, 0x19 }, + { "Meta", 0x00, 0x1a }, + { "MsgID", 0x00, 0x1b }, + { "MsgRef", 0x00, 0x1c }, + { "NoResp", 0x00, 0x1d }, + { "NoResults", 0x00, 0x1e }, + { "Put", 0x00, 0x1f }, + { "Replace", 0x00, 0x20 }, + { "RespURI", 0x00, 0x21 }, + { "Results", 0x00, 0x22 }, + { "Search", 0x00, 0x23 }, + { "Sequence", 0x00, 0x24 }, + { "SessionID", 0x00, 0x25 }, + { "SftDel", 0x00, 0x26 }, + { "Source", 0x00, 0x27 }, + { "SourceRef", 0x00, 0x28 }, + { "Status", 0x00, 0x29 }, + { "Sync", 0x00, 0x2a }, + { "SyncBody", 0x00, 0x2b }, + { "SyncHdr", 0x00, 0x2c }, + { "SyncML", 0x00, 0x2d }, + { "Target", 0x00, 0x2e }, + { "TargetRef", 0x00, 0x2f }, + { "Reserved for future use", 0x00, 0x30 }, + { "VerDTD", 0x00, 0x31 }, + { "VerProto", 0x00, 0x32 }, + { "NumberOfChanges",0x00, 0x33 }, + { "MoreData", 0x00, 0x34 }, + { "Field", 0x00, 0x35 }, + { "Filter", 0x00, 0x36 }, + { "Record", 0x00, 0x37 }, + { "FilterType", 0x00, 0x38 }, + { "SourceParent", 0x00, 0x39 }, + { "TargetParent", 0x00, 0x3a }, + { "Move", 0x00, 0x3b }, + { "Correlator", 0x00, 0x3c }, + + /* Code Page 1: MetInf */ + { "Anchor", 0x01, 0x05 }, + { "EMI", 0x01, 0x06 }, + { "Format", 0x01, 0x07 }, + { "FreeID", 0x01, 0x08 }, + { "FreeMem", 0x01, 0x09 }, + { "Last", 0x01, 0x0a }, + { "Mark", 0x01, 0x0b }, + { "MaxMsgSize", 0x01, 0x0c }, + { "Mem", 0x01, 0x0d }, + { "MetInf", 0x01, 0x0e }, + { "Next", 0x01, 0x0f }, + { "NextNonce", 0x01, 0x10 }, + { "SharedMem", 0x01, 0x11 }, + { "Size", 0x01, 0x12 }, + { "Type", 0x01, 0x13 }, + { "Version", 0x01, 0x14 }, + { "MaxObjSize", 0x01, 0x15 }, + { "FieldLevel", 0x01, 0x16 }, + { NULL, 0x00, 0x00 } +}; + + +/********************************************************* + * SyncML DevInf 1.2 ("OMA-TS-DS_DevInf-V1_2-20060710-A.pdf") + */ + +const WBXMLTagEntry sv_syncml_devinf12_tag_table[] = { + { "CTCap", 0x00, 0x05 }, + { "CTType", 0x00, 0x06 }, + { "DataStore", 0x00, 0x07 }, + { "DataType", 0x00, 0x08 }, + { "DevID", 0x00, 0x09 }, + { "DevInf", 0x00, 0x0a }, + { "DevTyp", 0x00, 0x0b }, + { "DisplayName", 0x00, 0x0c }, + { "DSMem", 0x00, 0x0d }, + { "Ext", 0x00, 0x0e }, + { "FwV", 0x00, 0x0f }, + { "HwV", 0x00, 0x10 }, + { "Man", 0x00, 0x11 }, + { "MaxGUIDSize", 0x00, 0x12 }, + { "MaxID", 0x00, 0x13 }, + { "MaxMem", 0x00, 0x14 }, + { "Mod", 0x00, 0x15 }, + { "OEM", 0x00, 0x16 }, + { "ParamName", 0x00, 0x17 }, + { "PropName", 0x00, 0x18 }, + { "Rx", 0x00, 0x19 }, + { "Rx-Pref", 0x00, 0x1a }, + { "SharedMem", 0x00, 0x1b }, + { "MaxSize", 0x00, 0x1c }, + { "SourceRef", 0x00, 0x1d }, + { "SwV", 0x00, 0x1e }, + { "SyncCap", 0x00, 0x1f }, + { "SyncType", 0x00, 0x20 }, + { "Tx", 0x00, 0x21 }, + { "Tx-Pref", 0x00, 0x22 }, + { "ValEnum", 0x00, 0x23 }, + { "VerCT", 0x00, 0x24 }, + { "VerDTD", 0x00, 0x25 }, + { "XNam", 0x00, 0x26 }, + { "XVal", 0x00, 0x27 }, + { "UTC", 0x00, 0x28 }, + { "SupportNumberOfChanges", 0x00, 0x29 }, + { "SupportLargeObjs", 0x00, 0x2a }, + { "Property", 0x00, 0x2b }, + { "PropParam", 0x00, 0x2c }, + { "MaxOccur", 0x00, 0x2d }, + { "NoTruncate", 0x00, 0x2e }, + { "Filter-Rx", 0x00, 0x30 }, + { "FilterCap", 0x00, 0x31 }, + { "FilterKeyword", 0x00, 0x32 }, + { "FieldLevel", 0x00, 0x33 }, + { "SupportHierarchicalSync", 0x00, 0x34 }, + { NULL, 0x00, 0x00 } +}; + + +const WBXMLNameSpaceEntry sv_syncml_devinf12_ns_table[] = { + { "syncml:devinf", 0x00 }, /**< Code Page 0: devinf */ + { NULL, 0x00 } +}; + + +/********************************************************* + * SyncML MetInf 1.2 ("OMA-TS-SyncML_MetaInfo-V1_2-20050509-C.pdf") + */ + +const WBXMLTagEntry sv_syncml_metinf12_tag_table[] = { + { "Anchor", 0x01, 0x05 }, + { "EMI", 0x01, 0x06 }, + { "Format", 0x01, 0x07 }, + { "FreeID", 0x01, 0x08 }, + { "FreeMem", 0x01, 0x09 }, + { "Last", 0x01, 0x0a }, + { "Mark", 0x01, 0x0b }, + { "MaxMsgSize", 0x01, 0x0c }, + { "Mem", 0x01, 0x0d }, + { "MetInf", 0x01, 0x0e }, + { "Next", 0x01, 0x0f }, + { "NextNonce", 0x01, 0x10 }, + { "SharedMem", 0x01, 0x11 }, + { "Size", 0x01, 0x12 }, + { "Type", 0x01, 0x13 }, + { "Version", 0x01, 0x14 }, + { "MaxObjSize", 0x01, 0x15 }, + { "FieldLevel", 0x01, 0x16 }, + { NULL, 0x00, 0x00 } +}; + +/********************************************************* + * SyncML DM DDF 1.2 ("OMA-TS-DM_TND-V1_2_1-20080617-A.pdf") + */ + +const WBXMLTagEntry sv_syncml_dmddf12_tag_table[] = { + { "AccessType", 0x02, 0x05 }, + { "ACL", 0x02, 0x06 }, + { "Add", 0x02, 0x07 }, + { "b64", 0x02, 0x08 }, + { "bin", 0x02, 0x09 }, + { "bool", 0x02, 0x0A }, + { "chr", 0x02, 0x0B }, + { "CaseSense", 0x02, 0x0C }, + { "CIS", 0x02, 0x0D }, + { "Copy", 0x02, 0x0E }, + { "CS", 0x02, 0x0F }, + { "date", 0x02, 0x10 }, + { "DDFName", 0x02, 0x11 }, + { "DefaultValue", 0x02, 0x12 }, + { "Delete", 0x02, 0x13 }, + { "Description", 0x02, 0x14 }, + { "DFFormat", 0x02, 0x15 }, + { "DFProperties", 0x02, 0x16 }, + { "DFTitle", 0x02, 0x17 }, + { "DFType", 0x02, 0x18 }, + { "Dynamic", 0x02, 0x19 }, + { "Exec", 0x02, 0x1A }, + { "float", 0x02, 0x1B }, + { "Format", 0x02, 0x1C }, + { "Get", 0x02, 0x1D }, + { "int", 0x02, 0x1E }, + { "Man", 0x02, 0x1F }, + { "MgmtTree", 0x02, 0x20 }, + { "MIME", 0x02, 0x21 }, + { "Mod", 0x02, 0x22 }, + { "Name", 0x02, 0x23 }, + { "Node", 0x02, 0x24 }, + { "node", 0x02, 0x25 }, + { "NodeName", 0x02, 0x26 }, + { "null", 0x02, 0x27 }, + { "Occurrence", 0x02, 0x28 }, + { "One", 0x02, 0x29 }, + { "OneOrMore", 0x02, 0x2A }, + { "OneOrN", 0x02, 0x2B }, + { "Path", 0x02, 0x2C }, + { "Permanent", 0x02, 0x2D }, + { "Replace", 0x02, 0x2E }, + { "RTProperties", 0x02, 0x2F }, + { "Scope", 0x02, 0x30 }, + { "Size", 0x02, 0x31 }, + { "time", 0x02, 0x32 }, + { "Title", 0x02, 0x33 }, + { "TStamp", 0x02, 0x34 }, + { "Type", 0x02, 0x35 }, + { "Value", 0x02, 0x36 }, + { "VerDTD", 0x02, 0x37 }, + { "VerNo", 0x02, 0x38 }, + { "xml", 0x02, 0x39 }, + { "ZeroOrMore", 0x02, 0x3A }, + { "ZeroOrN", 0x02, 0x3B }, + { "ZeroOrOne", 0x02, 0x3C }, + { NULL, 0x00, 0x00 } +}; + +const WBXMLNameSpaceEntry sv_syncml_dmddf12_ns_table[] = { + { "syncml:dmddf1.2", 0x02 }, /**< Code Page 2: OMA DM DDF */ + { NULL, 0x00 } +}; + +#endif /* WBXML_SUPPORT_SYNCML */ + + +#if defined( WBXML_SUPPORT_WV ) + +/***************************************************************************** + * Wireless Village CSP 1.1 ("OMA-WV-CSP-V1_1-20021001-A.pdf") + * Wireless Village CSP 1.2 ("OMA-IMPS-WV-CSP_WBXML-V1_2-20040522-C.pdf") + */ + +const WBXMLTagEntry sv_wv_csp_tag_table[] = { + /* Common ... continue on Page 0x09 */ + { "Acceptance", 0x00, 0x05 }, + { "AddList", 0x00, 0x06 }, + { "AddNickList", 0x00, 0x07 }, + { "ClientID", 0x00, 0x0A }, + { "Code", 0x00, 0x0B }, + { "ContactList", 0x00, 0x0C }, + { "ContentData", 0x00, 0x0D }, + { "ContentEncoding",0x00, 0x0E }, + { "ContentSize", 0x00, 0x0F }, + { "ContentType", 0x00, 0x10 }, + { "DateTime", 0x00, 0x11 }, + { "Description", 0x00, 0x12 }, + { "DetailedResult", 0x00, 0x13 }, + { "EntityList", 0x00, 0x14 }, + { "Group", 0x00, 0x15 }, + { "GroupID", 0x00, 0x16 }, + { "GroupList", 0x00, 0x17 }, + { "InUse", 0x00, 0x18 }, + { "Logo", 0x00, 0x19 }, + { "MessageCount", 0x00, 0x1A }, + { "MessageID", 0x00, 0x1B }, + { "MessageURI", 0x00, 0x1C }, + { "MSISDN", 0x00, 0x1D }, + { "Name", 0x00, 0x1E }, + { "NickList", 0x00, 0x1F }, + { "NickName", 0x00, 0x20 }, + { "Poll", 0x00, 0x21 }, + { "Presence", 0x00, 0x22 }, + { "PresenceSubList",0x00, 0x23 }, + { "PresenceValue", 0x00, 0x24 }, + { "Property", 0x00, 0x25 }, + { "Qualifier", 0x00, 0x26 }, + { "Recipient", 0x00, 0x27 }, + { "RemoveList", 0x00, 0x28 }, + { "RemoveNickList", 0x00, 0x29 }, + { "Result", 0x00, 0x2A }, + { "ScreenName", 0x00, 0x2B }, + { "Sender", 0x00, 0x2C }, + { "Session", 0x00, 0x2D }, + { "SessionDescriptor", 0x00, 0x2E }, + { "SessionID", 0x00, 0x2F }, + { "SessionType", 0x00, 0x30 }, + { "SName", 0x00, 0x08 }, + { "Status", 0x00, 0x31 }, + { "Transaction", 0x00, 0x32 }, + { "TransactionContent", 0x00, 0x33 }, + { "TransactionDescriptor", 0x00, 0x34 }, + { "TransactionID", 0x00, 0x35 }, + { "TransactionMode",0x00, 0x36 }, + { "URL", 0x00, 0x37 }, + { "URLList", 0x00, 0x38 }, + { "User", 0x00, 0x39 }, + { "UserID", 0x00, 0x3A }, + { "UserList", 0x00, 0x3B }, + { "Validity", 0x00, 0x3C }, + { "Value", 0x00, 0x3D }, + { "WV-CSP-Message", 0x00, 0x09 }, + + /* Access ... continue on Page 0x0A */ + { "AgreedCapabilityList", 0x01, 0x3A }, /* WV 1.2 */ + { "AllFunctions", 0x01, 0x05 }, + { "AllFunctionsRequest", 0x01, 0x06 }, + { "CancelInvite-Request", 0x01, 0x07 }, + { "CancelInviteUser-Request", 0x01, 0x08 }, + { "Capability", 0x01, 0x09 }, + { "CapabilityList", 0x01, 0x0A }, + { "CapabilityRequest", 0x01, 0x0B }, + { "ClientCapability-Request", 0x01, 0x0C }, + { "ClientCapability-Response", 0x01, 0x0D }, + { "CompletionFlag", 0x01, 0x34 }, + { "DigestBytes", 0x01, 0x0E }, + { "DigestSchema", 0x01, 0x0F }, + { "Disconnect", 0x01, 0x10 }, + { "Extended-Request", 0x01, 0x38 }, /* WV 1.2 */ + { "Extended-Response", 0x01, 0x39 }, /* WV 1.2 */ + { "Extended-Data", 0x01, 0x3B }, /* WV 1.2 */ + { "Functions", 0x01, 0x11 }, + { "GetSPInfo-Request", 0x01, 0x12 }, + { "GetSPInfo-Response", 0x01, 0x13 }, + { "InviteID", 0x01, 0x14 }, + { "InviteNote", 0x01, 0x15 }, + { "Invite-Request", 0x01, 0x16 }, + { "Invite-Response", 0x01, 0x17 }, + { "InviteType", 0x01, 0x18 }, + { "InviteUser-Request", 0x01, 0x19 }, + { "InviteUser-Response", 0x01, 0x1A }, + { "KeepAlive-Request", 0x01, 0x1B }, + { "KeepAlive-Response", 0x01, 0x29 }, + { "KeepAliveTime", 0x01, 0x1C }, + { "Login-Request", 0x01, 0x1D }, + { "Login-Response", 0x01, 0x1E }, + { "Logout-Request", 0x01, 0x1F }, + { "Nonce", 0x01, 0x20 }, + { "OtherServer", 0x01, 0x3C }, /* WV 1.2 */ + { "Password", 0x01, 0x21 }, + { "Polling-Request", 0x01, 0x22 }, + { "PresenceAttributeNSName",0x01, 0x3D }, /* WV 1.2 */ + { "ReceiveList", 0x01, 0x36 }, /* WV 1.2 */ + { "ResponseNote", 0x01, 0x23 }, + { "SearchElement", 0x01, 0x24 }, + { "SearchFindings", 0x01, 0x25 }, + { "SearchID", 0x01, 0x26 }, + { "SearchIndex", 0x01, 0x27 }, + { "SearchLimit", 0x01, 0x28 }, + { "SearchPairList", 0x01, 0x2A }, + { "Search-Request", 0x01, 0x2B }, + { "Search-Response", 0x01, 0x2C }, + { "SearchResult", 0x01, 0x2D }, + { "SearchString", 0x01, 0x33 }, + { "Service-Request", 0x01, 0x2E }, + { "Service-Response", 0x01, 0x2F }, + { "SessionCookie", 0x01, 0x30 }, + { "SessionNSName", 0x01, 0x3E }, /* WV 1.2 */ + { "StopSearch-Request", 0x01, 0x31 }, + { "TimeToLive", 0x01, 0x32 }, + { "TransactionNSName", 0x01, 0x3F }, /* WV 1.2 */ + { "VerifyID-Request", 0x01, 0x37 }, /* WV 1.2 */ + + /* Service ... continue on Page 0x08 */ + { "ADDGM", 0x02, 0x05 }, + { "AttListFunc", 0x02, 0x06 }, + { "BLENT", 0x02, 0x07 }, + { "CAAUT", 0x02, 0x08 }, + { "CAINV", 0x02, 0x09 }, + { "CALI", 0x02, 0x0A }, + { "CCLI", 0x02, 0x0B }, + { "ContListFunc", 0x02, 0x0C }, + { "CREAG", 0x02, 0x0D }, + { "DALI", 0x02, 0x0E }, + { "DCLI", 0x02, 0x0F }, + { "DELGR", 0x02, 0x10 }, + { "FundamentalFeat",0x02, 0x11 }, + { "FWMSG", 0x02, 0x12 }, + { "GALS", 0x02, 0x13 }, + { "GCLI", 0x02, 0x14 }, + { "GETGM", 0x02, 0x15 }, + { "GETGP", 0x02, 0x16 }, + { "GETLM", 0x02, 0x17 }, + { "GETM", 0x02, 0x18 }, + { "GETPR", 0x02, 0x19 }, + { "GETSPI", 0x02, 0x1A }, + { "GETWL", 0x02, 0x1B }, + { "GLBLU", 0x02, 0x1C }, + { "GRCHN", 0x02, 0x1D }, + { "GroupAuthFunc", 0x02, 0x1E }, + { "GroupFeat", 0x02, 0x1F }, + { "GroupMgmtFunc", 0x02, 0x20 }, + { "GroupUseFunc", 0x02, 0x21 }, + { "IMAuthFunc", 0x02, 0x22 }, + { "IMFeat", 0x02, 0x23 }, + { "IMReceiveFunc", 0x02, 0x24 }, + { "IMSendFunc", 0x02, 0x25 }, + { "INVIT", 0x02, 0x26 }, + { "InviteFunc", 0x02, 0x27 }, + { "MBRAC", 0x02, 0x28 }, + { "MCLS", 0x02, 0x29 }, + { "MF", 0x02, 0x3D }, /* WV 1.2 */ + { "MG", 0x02, 0x3E }, /* WV 1.2 */ + { "MM", 0x02, 0x3F }, /* WV 1.2 */ + { "MDELIV", 0x02, 0x2A }, + { "NEWM", 0x02, 0x2B }, + { "NOTIF", 0x02, 0x2C }, + { "PresenceAuthFunc", 0x02, 0x2D }, + { "PresenceDeliverFunc",0x02, 0x2E }, + { "PresenceFeat", 0x02, 0x2F }, + { "REACT", 0x02, 0x30 }, + { "REJCM", 0x02, 0x31 }, + { "REJEC", 0x02, 0x32 }, + { "RMVGM", 0x02, 0x33 }, + { "SearchFunc", 0x02, 0x34 }, + { "ServiceFunc", 0x02, 0x35 }, + { "SETD", 0x02, 0x36 }, + { "SETGP", 0x02, 0x37 }, + { "SRCH", 0x02, 0x38 }, + { "STSRC", 0x02, 0x39 }, + { "SUBGCN", 0x02, 0x3A }, + { "UPDPR", 0x02, 0x3B }, + { "WVCSPFeat", 0x02, 0x3C }, + + /* Client Capability */ + { "AcceptedCharset", 0x03, 0x05 }, + { "AcceptedContentLength", 0x03, 0x06 }, + { "AcceptedContentType", 0x03, 0x07 }, + { "AcceptedTransferEncoding", 0x03, 0x08 }, + { "AnyContent", 0x03, 0x09 }, + { "DefaultLanguage", 0x03, 0x0A }, + { "InitialDeliveryMethod", 0x03, 0x0B }, + { "MultiTrans", 0x03, 0x0C }, + { "ParserSize", 0x03, 0x0D }, + { "ServerPollMin", 0x03, 0x0E }, + { "SupportedBearer", 0x03, 0x0F }, + { "SupportedCIRMethod", 0x03, 0x10 }, + { "TCPAddress", 0x03, 0x11 }, + { "TCPPort", 0x03, 0x12 }, + { "UDPPort", 0x03, 0x13 }, + + /* Presence Primitive */ + { "Auto-Subscribe", 0x04, 0x1E }, /* WV 1.2 */ + { "CancelAuth-Request", 0x04, 0x05 }, + { "ContactListProperties", 0x04, 0x06 }, + { "CreateAttributeList-Request", 0x04, 0x07 }, + { "CreateList-Request", 0x04, 0x08 }, + { "DefaultAttributeList", 0x04, 0x09 }, + { "DefaultContactList", 0x04, 0x0A }, + { "DefaultList", 0x04, 0x0B }, + { "DeleteAttributeList-Request", 0x04, 0x0C }, + { "DeleteList-Request", 0x04, 0x0D }, + { "GetAttributeList-Request", 0x04, 0x0E }, + { "GetAttributeList-Response", 0x04, 0x0F }, + { "GetList-Request", 0x04, 0x10 }, + { "GetList-Response", 0x04, 0x11 }, + { "GetPresence-Request", 0x04, 0x12 }, + { "GetPresence-Response", 0x04, 0x13 }, + { "GetReactiveAuthStatus-Request", 0x04, 0x1F }, /* WV 1.2 */ + { "GetReactiveAuthStatus-Response", 0x04, 0x20 }, /* WV 1.2 */ + { "GetWatcherList-Request", 0x04, 0x14 }, + { "GetWatcherList-Response", 0x04, 0x15 }, + { "ListManage-Request", 0x04, 0x16 }, + { "ListManage-Response", 0x04, 0x17 }, + { "PresenceAuth-Request", 0x04, 0x19 }, + { "PresenceAuth-User", 0x04, 0x1A }, + { "PresenceNotification-Request", 0x04, 0x1B }, + { "SubscribePresence-Request", 0x04, 0x1D }, + { "UnsubscribePresence-Request", 0x04, 0x18 }, + { "UpdatePresence-Request", 0x04, 0x1C }, + + /* Presence Attribute */ + { "Accuracy", 0x05, 0x05 }, + { "Address", 0x05, 0x06 }, + { "AddrPref", 0x05, 0x07 }, + { "Alias", 0x05, 0x08 }, + { "Altitude", 0x05, 0x09 }, + { "Building", 0x05, 0x0A }, + { "Caddr", 0x05, 0x0B }, + { "Cap", 0x05, 0x2F }, + { "City", 0x05, 0x0C }, + { "ClientInfo", 0x05, 0x0D }, + { "ClientProducer", 0x05, 0x0E }, + { "ClientType", 0x05, 0x0F }, + { "ClientVersion", 0x05, 0x10 }, + { "Cname", 0x05, 0x30 }, + { "CommC", 0x05, 0x11 }, + { "CommCap", 0x05, 0x12 }, + { "Contact", 0x05, 0x31 }, + { "ContactInfo", 0x05, 0x13 }, + { "ContainedvCard", 0x05, 0x14 }, + /* WV 1.2: removed in last version */ + { "Country", 0x05, 0x15 }, + { "Cpriority", 0x05, 0x32 }, + { "Crossing1", 0x05, 0x16 }, + { "Crossing2", 0x05, 0x17 }, + { "Cstatus", 0x05, 0x33 }, + { "DevManufacturer", 0x05, 0x18 }, + { "DirectContent", 0x05, 0x19 }, + { "FreeTextLocation", 0x05, 0x1A }, + { "GeoLocation", 0x05, 0x1B }, + { "Inf_link", 0x05, 0x37 }, /* WV 1.2 */ + { "InfoLink", 0x05, 0x38 }, /* WV 1.2 */ + { "Language", 0x05, 0x1C }, + { "Latitude", 0x05, 0x1D }, + { "Link", 0x05, 0x39 }, /* WV 1.2 */ + { "Longitude", 0x05, 0x1E }, + { "Model", 0x05, 0x1F }, + { "NamedArea", 0x05, 0x20 }, + { "Note", 0x05, 0x34 }, /* WV 1.2 */ + { "OnlineStatus", 0x05, 0x21 }, + { "PLMN", 0x05, 0x22 }, + { "PrefC", 0x05, 0x23 }, + { "PreferredContacts", 0x05, 0x24 }, + { "PreferredLanguage", 0x05, 0x25 }, + { "PreferredContent", 0x05, 0x26 }, + { "PreferredvCard", 0x05, 0x27 }, + { "Registration", 0x05, 0x28 }, + { "StatusContent", 0x05, 0x29 }, + { "StatusMood", 0x05, 0x2A }, + { "StatusText", 0x05, 0x2B }, + { "Street", 0x05, 0x2C }, + { "Text", 0x05, 0x3A }, /* WV 1.2 */ + { "TimeZone", 0x05, 0x2D }, + { "UserAvailability", 0x05, 0x2E }, + { "Zone", 0x05, 0x35 }, + + /* Messaging */ + { "BlockList", 0x06, 0x05 }, + { "BlockEntity-Request", 0x06, 0x06 }, /* WV 1.2 : changed from 'BlockUser-Request' in WV 1.1 */ + { "DeliveryMethod", 0x06, 0x07 }, + { "DeliveryReport", 0x06, 0x08 }, + { "DeliveryReport-Request", 0x06, 0x09 }, + { "DeliveryTime", 0x06, 0x1A }, + { "ForwardMessage-Request", 0x06, 0x0A }, + { "GetBlockedList-Request", 0x06, 0x0B }, + { "GetBlockedList-Response", 0x06, 0x0C }, + { "GetMessageList-Request", 0x06, 0x0D }, + { "GetMessageList-Response", 0x06, 0x0E }, + { "GetMessage-Request", 0x06, 0x0F }, + { "GetMessage-Response", 0x06, 0x10 }, + { "GrantList", 0x06, 0x11 }, + { "MessageDelivered", 0x06, 0x12 }, + { "MessageInfo", 0x06, 0x13 }, + { "MessageNotification", 0x06, 0x14 }, + { "NewMessage", 0x06, 0x15 }, + { "RejectMessage-Request", 0x06, 0x16 }, + { "SendMessage-Request", 0x06, 0x17 }, + { "SendMessage-Response", 0x06, 0x18 }, + { "SetDeliveryMethod-Request", 0x06, 0x19 }, + + /* Group */ + { "AddGroupMembers-Request", 0x07, 0x05 }, + { "Admin", 0x07, 0x06 }, + { "AdminMapList", 0x07, 0x26 }, /* WV 1.2 */ + { "AdminMapping", 0x07, 0x27 }, /* WV 1.2 */ + { "CreateGroup-Request", 0x07, 0x07 }, + { "DeleteGroup-Request", 0x07, 0x08 }, + { "GetGroupMembers-Request", 0x07, 0x09 }, + { "GetGroupMembers-Response", 0x07, 0x0A }, + { "GetGroupProps-Request", 0x07, 0x0B }, + { "GetGroupProps-Response", 0x07, 0x0C }, + { "GetJoinedUsers-Request", 0x07, 0x24 }, /* WV 1.2 */ + { "GetJoinedUsers-Response", 0x07, 0x25 }, /* WV 1.2 */ + { "GroupChangeNotice", 0x07, 0x0D }, + { "GroupProperties", 0x07, 0x0E }, + { "Joined", 0x07, 0x0F }, + { "JoinGroup", 0x07, 0x21 }, + { "JoinedRequest", 0x07, 0x10 }, + { "JoinGroup-Request", 0x07, 0x11 }, + { "JoinGroup-Response", 0x07, 0x12 }, + { "LeaveGroup-Request", 0x07, 0x13 }, + { "LeaveGroup-Response", 0x07, 0x14 }, + { "Left", 0x07, 0x15 }, + { "Mapping", 0x07, 0x28 }, /* WV 1.2 */ + { "MemberAccess-Request", 0x07, 0x16 }, + { "Mod", 0x07, 0x17 }, + { "ModMapping", 0x07, 0x29 }, /* WV 1.2 */ + { "OwnProperties", 0x07, 0x18 }, + { "RejectList-Request", 0x07, 0x19 }, + { "RejectList-Response", 0x07, 0x1A }, + { "RemoveGroupMembers-Request", 0x07, 0x1B }, + { "SetGroupProps-Request", 0x07, 0x1C }, + { "SubscribeGroupNotice-Request", 0x07, 0x1D }, + { "SubscribeGroupNotice-Response", 0x07, 0x1E }, + { "SubscribeNotification", 0x07, 0x22 }, + { "SubscribeType", 0x07, 0x23 }, + { "UserMapList", 0x07, 0x2A }, /* WV 1.2 */ + { "UserMapping", 0x07, 0x2B }, /* WV 1.2 */ + { "Users", 0x07, 0x1F }, + { "WelcomeNote", 0x07, 0x20 }, + + /* Service ... continued */ + { "GETAUT", 0x08, 0x06 }, /* WV 1.2 */ + { "GETJU", 0x08, 0x07 }, /* WV 1.2 */ + { "MP", 0x08, 0x05 }, /* WV 1.2 */ + { "VRID", 0x08, 0x08 }, /* WV 1.2 */ + { "VerifyIDFunc", 0x08, 0x09 }, /* WV 1.2 */ + + /* Common ... continued */ + { "CIR", 0x09, 0x05 }, /* WV 1.2 */ + { "Domain", 0x09, 0x06 }, /* WV 1.2 */ + { "ExtBlock", 0x09, 0x07 }, /* WV 1.2 */ + { "HistoryPeriod", 0x09, 0x08 }, /* WV 1.2 */ + { "IDList", 0x09, 0x09 }, /* WV 1.2 */ + { "MaxWatcherList", 0x09, 0x0A }, /* WV 1.2 */ + { "ReactiveAuthState", 0x09, 0x0B }, /* WV 1.2 */ + { "ReactiveAuthStatus", 0x09, 0x0C }, /* WV 1.2 */ + { "ReactiveAuthStatusList", 0x09, 0x0D }, /* WV 1.2 */ + { "Watcher", 0x09, 0x0E }, /* WV 1.2 */ + { "WatcherStatus", 0x09, 0x0F }, /* WV 1.2 */ + + /* Access ... continued */ + { "WV-CSP-VersionDiscovery-Request", 0x0A, 0x05 }, /* WV 1.2 */ + { "WV-CSP-VersionDiscovery-Response", 0x0A, 0x06 }, /* WV 1.2 */ + { "VersionList", 0x0A, 0x07 }, /* WV 1.2 */ + + { NULL, 0x00, 0x00 } +}; + +const WBXMLAttrEntry sv_wv_csp_attr_table[] = { + { "xmlns", "http://www.wireless-village.org/CSP", 0x00, 0x05 }, + { "xmlns", "http://www.wireless-village.org/PA", 0x00, 0x06 }, + { "xmlns", "http://www.wireless-village.org/TRC", 0x00, 0x07 }, + { "xmlns", "http://www.openmobilealliance.org/DTD/WV-CSP", 0x00, 0x08 }, + { "xmlns", "http://www.openmobilealliance.org/DTD/WV-PA", 0x00, 0x09 }, + { "xmlns", "http://www.openmobilealliance.org/DTD/WV-TRC", 0x00, 0x0A }, + { NULL, NULL, 0x00, 0x00 } +}; + +const WBXMLExtValueEntry sv_wv_csp_ext_table[] = { + /* + * DO NOT CHANGE THIS TABLE ORDER PLEASE ! + * Extension Tokens must be sorted by length ! + */ + + { "application/vnd.wap.mms-message", 0x04 }, /* Common value token */ + { "www.wireless-village.org", 0x30 }, /* Common value token */ + { "GROUP_USER_ID_AUTOJOIN", 0x50 }, /* Access value token */ /* WV 1.2 */ + { "GROUP_USER_ID_JOINED", 0x40 }, /* Access value token */ + { "GROUP_USER_ID_OWNER", 0x41 }, /* Access value token */ + { "USER_EMAIL_ADDRESS", 0x47 }, /* Access value token */ + { "USER_MOBILE_NUMBER", 0x4b }, /* Access value token */ + { "USER_ONLINE_STATUS", 0x4c }, /* Access value token */ + { "application/x-sms", 0x05 }, /* Common value token */ + { "PrivateMessaging", 0x1c }, /* Common value token */ + { "text/x-vCalendar", 0x29 }, /* Common value token */ + { "USER_FIRST_NAME", 0x48 }, /* Access value token */ + { "MaxActiveUsers", 0x13 }, /* Common value token */ + { "PrivilegeLevel", 0x1d }, /* Common value token */ + { "USER_LAST_NAME", 0x4a }, /* Access value token */ + { "NOT_AVAILABLE", 0x70 }, /* Presence value token */ + { "application/", 0x03 }, /* Common value token */ + { "text/x-vCard", 0x2a }, /* Common value token */ + { "MOBILE_PHONE", 0x6f }, /* Presence value token */ + { "VIDEO_STREAM", 0x77 }, /* Presence value token */ + { "ActiveUsers", 0x01 }, /* Common value token */ + { "DisplayName", 0x0a }, /* Common value token */ + { "GROUP_TOPIC", 0x3f }, /* Access value token */ + { "AccessType", 0x00 }, /* Common value token */ + { "AutoDelete", 0x31 }, /* Common value token */ /* WV 1.2 */ + { "Restricted", 0x22 }, /* Common value token */ + { "ScreenName", 0x23 }, /* Common value token */ + { "Searchable", 0x24 }, /* Common value token */ + { "text/plain", 0x28 }, /* Common value token */ + { "GROUP_NAME", 0x3e }, /* Access value token */ + { "USER_ALIAS", 0x46 }, /* Access value token */ + { "AUDIO_CALL", 0x5e }, /* Presence value token */ + { "IM_OFFLINE", 0x69 }, /* Presence value token */ + { "INVINCIBLE", 0x6c }, /* Presence value token */ + { "VIDEO_CALL", 0x76 }, /* Presence value token */ + { "AVAILABLE", 0x5f }, /* Presence value token */ + { "IM_ONLINE", 0x6a }, /* Presence value token */ + { "https://", 0x0f }, /* Common value token */ + { "AutoJoin", 0x06 }, /* Common value token */ + { "Response", 0x21 }, /* Common value token */ + { "Validity", 0x33 }, /* Common value token */ /* WV 1.2 */ + { "GROUP_ID", 0x3d }, /* Access value token */ + { "COMPUTER", 0x63 }, /* Presence value token */ + { "DISCREET", 0x64 }, /* Presence value token */ + { "Default", 0x09 }, /* Common value token */ + { "GRANTED", 0x35 }, /* Common value token */ /* WV 1.2 */ + { "http://", 0x0e }, /* Common value token */ + { "Outband", 0x19 }, /* Common value token */ + { "PENDING", 0x36 }, /* Common value token */ /* WV 1.2 */ + { "Private", 0x1b }, /* Common value token */ + { "Request", 0x20 }, /* Common value token */ + { "USER_ID", 0x49 }, /* Access value token */ + { "ANXIOUS", 0x5c }, /* Presence value token */ + { "ASHAMED", 0x5d }, /* Presence value token */ + { "EXCITED", 0x66 }, /* Presence value token */ + { "IN_LOVE", 0x6b }, /* Presence value token */ + { "JEALOUS", 0x6d }, /* Presence value token */ + { "BASE64", 0x07 }, /* Common value token */ + { "Closed", 0x08 }, /* Common value token */ + { "image/", 0x10 }, /* Common value token */ + { "Inband", 0x11 }, /* Common value token */ + { "Public", 0x1e }, /* Common value token */ + { "DENIED", 0x34 }, /* Common value token */ /* WV 1.2 */ + { "WAPSMS", 0x4d }, /* Access value token */ + { "WAPUDP", 0x4e }, /* Access value token */ + { "SLEEPY", 0x74 }, /* Presence value token */ + { "ShowID", 0x37 }, /* Common value token */ /* WV 1.2 */ + { "Admin", 0x02 }, /* Common value token */ + { "text/", 0x27 }, /* Common value token */ + { "Topic", 0x2b }, /* Common value token */ + { "ANGRY", 0x5b }, /* Presence value token */ + { "BORED", 0x60 }, /* Presence value token */ + { "EMAIL", 0x65 }, /* Presence value token */ + { "HAPPY", 0x67 }, /* Presence value token */ + { "OTHER", 0x71 }, /* Presence value token */ + { "Name", 0x15 }, /* Common value token */ + { "None", 0x16 }, /* Common value token */ + { "Open", 0x18 }, /* Common value token */ + { "Type", 0x2d }, /* Common value token */ + { "HTTP", 0x42 }, /* Access value token */ + { "STCP", 0x44 }, /* Access value token */ + { "SUDP", 0x45 }, /* Access value token */ + { "CALL", 0x61 }, /* Presence value token */ + { "Mod", 0x14 }, /* Common value token */ + { "SMS", 0x43 }, /* Access value token */ + { "WSP", 0x4f }, /* Access value token */ + { "CLI", 0x62 }, /* Presence value token */ + { "MMS", 0x6e }, /* Presence value token */ + { "PDA", 0x72 }, /* Presence value token */ + { "SAD", 0x73 }, /* Presence value token */ + { "SMS", 0x75 }, /* Presence value token */ + { "GM", 0x32 }, /* Common value token */ /* WV 1.2 */ + { "GR", 0x0d }, /* Common value token */ + { "IM", 0x12 }, /* Common value token */ + { "PR", 0x1a }, /* Common value token */ + { "SC", 0x26 }, /* Common value token */ + { "US", 0x2f }, /* Common value token */ + { "IM", 0x68 }, /* Presence value token */ /* Obsolete in WV 1.2 */ + { "F", 0x0b }, /* Common value token */ + { "G", 0x0c }, /* Common value token */ + { "N", 0x17 }, /* Common value token */ + { "P", 0x1f }, /* Common value token */ + { "S", 0x25 }, /* Common value token */ + { "T", 0x2c }, /* Common value token */ + { "U", 0x2e }, /* Common value token */ + + { NULL, 0x00 }, /* Presence value token */ +}; + +#endif /* WBXML_SUPPORT_WV */ + + +#if defined( WBXML_SUPPORT_AIRSYNC ) + +/************************************************* + * Microsoft ActiveSync (aka AirSync) + * + * Actually the table represent [MS-ASWBXML] 8.0. + * + * The version means the protocol version (e.g. v12.0). + * The revision means the revision of the specification document (e.g. r8.0). + * + * mainly used by Microsoft Exchange and + * modern mobiles from all vendors + */ + +const WBXMLTagEntry sv_airsync_tag_table[] = { + /* Code Page: "AirSync" (since v2.5 and r1.0) */ + { "Sync", 0x00, 0x05 }, /* since r1.0 */ + { "Responses", 0x00, 0x06 }, /* since r1.0 */ + { "Add", 0x00, 0x07 }, /* since r1.0 */ + { "Change", 0x00, 0x08 }, /* since r1.0 */ + { "Delete", 0x00, 0x09 }, /* since r1.0 */ + { "Fetch", 0x00, 0x0a }, /* since r1.0 */ + { "SyncKey", 0x00, 0x0b }, /* since r1.0 */ + { "ClientId", 0x00, 0x0c }, /* since r1.0 */ + { "ServerId", 0x00, 0x0d }, /* since r1.0 */ + { "Status", 0x00, 0x0e }, /* since r1.0 */ + { "Collection", 0x00, 0x0f }, /* since r1.0 */ + { "Class", 0x00, 0x10 }, /* since r1.0 */ + { "Version", 0x00, 0x11 }, /* not defined in r8.0 but in r1.0 */ + { "CollectionId", 0x00, 0x12 }, /* since r1.0 */ + { "GetChanges", 0x00, 0x13 }, /* since r1.0 */ + { "MoreAvailable", 0x00, 0x14 }, /* since r1.0 */ + { "WindowSize", 0x00, 0x15 }, /* since r1.0 */ + { "Commands", 0x00, 0x16 }, /* since r1.0 */ + { "Options", 0x00, 0x17 }, /* since r1.0 */ + { "FilterType", 0x00, 0x18 }, /* since r1.0 */ + { "Truncation", 0x00, 0x19 }, /* not defined in r8.0 but in r1.0 */ + { "RTFTruncation", 0x00, 0x1a }, /* corrected in libwbxml 0.11.0, not defined in r8.0 but in r1.0 */ + { "Conflict", 0x00, 0x1b }, /* since r1.0 */ + { "Collections", 0x00, 0x1c }, /* since r1.0 */ + { "ApplicationData", 0x00, 0x1d }, /* since r1.0 */ + { "DeletesAsMoves", 0x00, 0x1e }, /* since r1.0 */ + { "NotifyGUID", 0x00, 0x1f }, /* not defined in r8.0 but in r1.0 */ + { "Supported", 0x00, 0x20 }, /* since r1.0 */ + { "SoftDelete", 0x00, 0x21 }, /* since r1.0 */ + { "MIMESupport", 0x00, 0x22 }, /* since r1.0 */ + { "MIMETruncation", 0x00, 0x23 }, /* since r1.0 */ + { "Wait", 0x00, 0x24 }, /* since r1.0 */ + { "Limit", 0x00, 0x25 }, /* since r1.0 */ + { "Partial", 0x00, 0x26 }, /* since r1.0 */ + { "ConversationMode", 0x00, 0x27 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "MaxItems", 0x00, 0x28 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "HeartbeatInterval", 0x00, 0x29 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + + /* Code Page: Contacts (since v2.5 and r1.0) */ + { "Anniversary", 0x01, 0x05 }, /* since r1.0 */ + { "AssistantName", 0x01, 0x06 }, /* since r1.0 */ + { "AssistantTelephoneNumber", 0x01, 0x07 }, /* corrected in libwbxml 0.11.0 */ + { "Birthday", 0x01, 0x08 }, /* since r1.0 */ + { "Body", 0x01, 0x09 }, /* not defined in r8.0 but in r1.0 */ + { "BodySize", 0x01, 0x0a }, /* not defined in r8.0 but in r1.0 */ + { "BodyTruncated", 0x01, 0x0b }, /* not defined in r8.0 but in r1.0 */ + { "Business2PhoneNumber", 0x01, 0x0c }, /* changed in r8.0, r1.0: Business2TelephoneNumber */ + { "BusinessCity", 0x01, 0x0d }, /* since r1.0 */ + { "BusinessCountry", 0x01, 0x0e }, /* since r1.0 */ + { "BusinessPostalCode", 0x01, 0x0f }, /* since r1.0 */ + { "BusinessState", 0x01, 0x10 }, /* since r1.0 */ + { "BusinessStreet", 0x01, 0x11 }, /* since r1.0 */ + { "BusinessFaxNumber", 0x01, 0x12 }, /* since r1.0 */ + { "BusinessPhoneNumber", 0x01, 0x13 }, /* changed in r8.0, r1.0: BusinessTelephoneNumber */ + { "CarPhoneNumber", 0x01, 0x14 }, /* since r1.0 */ + { "Categories", 0x01, 0x15 }, /* since r1.0 */ + { "Category", 0x01, 0x16 }, /* since r1.0 */ + { "Children", 0x01, 0x17 }, /* since r1.0 */ + { "Child", 0x01, 0x18 }, /* since r1.0 */ + { "CompanyName", 0x01, 0x19 }, /* since r1.0 */ + { "Department", 0x01, 0x1a }, /* since r1.0 */ + { "Email1Address", 0x01, 0x1b }, /* since r1.0 */ + { "Email2Address", 0x01, 0x1c }, /* since r1.0 */ + { "Email3Address", 0x01, 0x1d }, /* since r1.0 */ + { "FileAs", 0x01, 0x1e }, /* since r1.0 */ + { "FirstName", 0x01, 0x1f }, /* since r1.0 */ + { "Home2PhoneNumber", 0x01, 0x20 }, /* changed in r8.0, r1.0: BusinessTelephoneNumber */ + { "HomeCity", 0x01, 0x21 }, /* since r1.0 */ + { "HomeCountry", 0x01, 0x22 }, /* since r1.0 */ + { "HomePostalCode", 0x01, 0x23 }, /* since r1.0 */ + { "HomeState", 0x01, 0x24 }, /* since r1.0 */ + { "HomeStreet", 0x01, 0x25 }, /* since r1.0 */ + { "HomeFaxNumber", 0x01, 0x26 }, /* since r1.0 */ + { "HomePhoneNumber", 0x01, 0x27 }, /* changed in r8.0, r1.0: BusinessTelephoneNumber */ + { "JobTitle", 0x01, 0x28 }, /* since r1.0 */ + { "LastName", 0x01, 0x29 }, /* since r1.0 */ + { "MiddleName", 0x01, 0x2a }, /* since r1.0 */ + { "MobilePhoneNumber", 0x01, 0x2b }, /* changed in r8.0, r1.0: BusinessTelephoneNumber */ + { "OfficeLocation", 0x01, 0x2c }, /* since r1.0 */ + { "OtherCity", 0x01, 0x2d }, /* since r1.0 */ + { "OtherCountry", 0x01, 0x2e }, /* since r1.0 */ + { "OtherPostalCode", 0x01, 0x2f }, /* since r1.0 */ + { "OtherState", 0x01, 0x30 }, /* since r1.0 */ + { "OtherStreet", 0x01, 0x31 }, /* since r1.0 */ + { "PagerNumber", 0x01, 0x32 }, /* since r1.0 */ + { "RadioPhoneNumber", 0x01, 0x33 }, /* changed in r8.0, r1.0: BusinessTelephoneNumber */ + { "Spouse", 0x01, 0x34 }, /* since r1.0 */ + { "Suffix", 0x01, 0x35 }, /* since r1.0 */ + { "Title", 0x01, 0x36 }, /* since r1.0 */ + { "WebPage", 0x01, 0x37 }, /* since r1.0 */ + { "YomiCompanyName", 0x01, 0x38 }, /* since r1.0 */ + { "YomiFirstName", 0x01, 0x39 }, /* since r1.0 */ + { "YomiLastName", 0x01, 0x3a }, /* since r1.0 */ + { "CompressedRTF", 0x01, 0x3b }, /* corrected in libwbxml 0.11.0, not defined in r8.0 but in r1.0 */ + { "Picture", 0x01, 0x3c }, /* since r1.0 */ + { "Alias", 0x01, 0x3d }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "WeightedRank", 0x01, 0x3e }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + + /* Code Page: Email (since v2.5 and r1.0) */ + { "Attachment", 0x02, 0x05 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Attachments", 0x02, 0x06 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "AttName", 0x02, 0x07 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "AttSize", 0x02, 0x08 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "AttOId", 0x02, 0x09 }, /* corrected in libwbxml 0.11.0, not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "AttMethod", 0x02, 0x0a }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "AttRemoved", 0x02, 0x0b }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Body", 0x02, 0x0c }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "BodySize", 0x02, 0x0d }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "BodyTruncated", 0x02, 0x0e }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "DateReceived", 0x02, 0x0f }, /* supported since v2.5 */ + { "DisplayName", 0x02, 0x10 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "DisplayTo", 0x02, 0x11 }, /* supported since v2.5 */ + { "Importance", 0x02, 0x12 }, /* supported since v2.5 */ + { "MessageClass", 0x02, 0x13 }, /* supported since v2.5 */ + { "Subject", 0x02, 0x14 }, /* supported since v2.5 */ + { "Read", 0x02, 0x15 }, /* supported since v2.5 */ + { "To", 0x02, 0x16 }, /* supported since v2.5 */ + { "Cc", 0x02, 0x17 }, /* supported since v2.5 */ + { "From", 0x02, 0x18 }, /* supported since v2.5 */ + { "Reply-To", 0x02, 0x19 }, /* supported since v2.5 */ + { "AllDayEvent", 0x02, 0x1a }, /* supported since v2.5 */ + { "Categories", 0x02, 0x1b }, /* r1.0: supported by v2.5, v12.0 and 12.1; BUT r8.0: not supported by 12.1 */ + { "Category", 0x02, 0x1c }, /* r1.0: supported by v2.5, v12.0 and 12.1; BUT r8.0: not supported by 12.1 */ + { "DTStamp", 0x02, 0x1d }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "EndTime", 0x02, 0x1e }, /* supported since v2.5 */ + { "InstanceType", 0x02, 0x1f }, /* supported since v2.5 */ + { "BusyStatus", 0x02, 0x20 }, /* supported since v2.5 */ + { "Location", 0x02, 0x21 }, /* supported since v2.5 */ + { "MeetingRequest", 0x02, 0x22 }, /* supported since v2.5 */ + { "Organizer", 0x02, 0x23 }, /* supported since v2.5 */ + { "RecurrenceId", 0x02, 0x24 }, /* supported since v2.5 */ + { "Reminder", 0x02, 0x25 }, /* supported since v2.5 */ + { "ResponseRequested", 0x02, 0x26 }, /* supported since v2.5 */ + { "Recurrences", 0x02, 0x27 }, /* supported since v2.5 */ + { "Recurrence", 0x02, 0x28 }, /* supported since v2.5 */ + { "Recurrence_Type", 0x02, 0x29 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_Until", 0x02, 0x2a }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_Occurrences", 0x02, 0x2b }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_Interval", 0x02, 0x2c }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_DayOfWeek", 0x02, 0x2d }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_DayOfMonth", 0x02, 0x2e }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_WeekOfMonth", 0x02, 0x2f }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_MonthOfYear", 0x02, 0x30 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "StartTime", 0x02, 0x31 }, /* supported since v2.5 */ + { "Sensitivity", 0x02, 0x32 }, /* supported since v2.5 */ + { "TimeZone", 0x02, 0x33 }, /* supported since v2.5 */ + { "GlobalObjId", 0x02, 0x34 }, /* supported since v2.5 */ + { "ThreadTopic", 0x02, 0x35 }, /* supported since v2.5 */ + { "MIMEData", 0x02, 0x36 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "MIMETruncated", 0x02, 0x37 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "MIMESize", 0x02, 0x38 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "InternetCPID", 0x02, 0x39 }, /* supported since v2.5 */ + { "Flag", 0x02, 0x3a }, /* supported since v12.0 */ + { "FlagStatus", 0x02, 0x3b }, /* supported since v12.0 */ + { "ContentClass", 0x02, 0x3c }, /* supported since v12.0 */ + { "FlagType", 0x02, 0x3d }, /* supported since v12.0 */ + { "CompleteTime", 0x02, 0x3e }, /* supported since v12.0 */ + { "DisallowNewTimeProposal",0x02, 0x3f }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + + /* Code Page: AirNotify */ + + /* There are conflicting version informations. + * + * r1.0: supported by v2.5, v12.0 and v12.1 + * r8.0: This code page is no longer in use. + * r8.0: Tokens 05 to 17 have been defined. + */ + + { "Notify", 0x03, 0x05 }, /* not defined in r8.0 but in r1.0, only supported by v2.0 and v2.5 */ + { "Notification", 0x03, 0x06 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Version", 0x03, 0x07 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "LifeTime", 0x03, 0x08 }, /* corrected in libwbxml 0.11.0, not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "DeviceInfo", 0x03, 0x09 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Enable", 0x03, 0x0a }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Folder", 0x03, 0x0b }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "ServerId", 0x03, 0x0c }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "DeviceAddress", 0x03, 0x0d }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "ValidCarrierProfiles", 0x03, 0x0e }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "CarrierProfile", 0x03, 0x0f }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Status", 0x03, 0x10 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Responses", 0x03, 0x11 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Devices", 0x03, 0x12 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Device", 0x03, 0x13 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Id", 0x03, 0x14 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Expiry", 0x03, 0x15 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "NotifyGUID", 0x03, 0x16 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "DeviceFriendlyName", 0x03, 0x17 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + + /* Code Page: Calendar (since v2.5 and r1.0) */ + { "TimeZone", 0x04, 0x05 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "AllDayEvent", 0x04, 0x06 }, /* supported since v2.5 */ + { "Attendees", 0x04, 0x07 }, /* supported since v2.5 */ + { "Attendee", 0x04, 0x08 }, /* supported since v2.5 */ + { "Attendee_Email", 0x04, 0x09 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Attendee_Name", 0x04, 0x0a }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Body", 0x04, 0x0b }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "BodyTruncated", 0x04, 0x0c }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "BusyStatus", 0x04, 0x0d }, /* supported since v2.5 */ + { "Categories", 0x04, 0x0e }, /* supported since v2.5 */ + { "Category", 0x04, 0x0f }, /* supported since v2.5 */ + { "Compressed_RTF", 0x04, 0x10 }, /* corrected in libwbxml 0.11.0, not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "DTStamp", 0x04, 0x11 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "EndTime", 0x04, 0x12 }, /* supported since v2.5 */ + { "Exception", 0x04, 0x13 }, /* supported since v2.5 */ + { "Exceptions", 0x04, 0x14 }, /* supported since v2.5 */ + { "Exception_Deleted", 0x04, 0x15 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: Exception_IsDeleted */ + { "Exception_StartTime", 0x04, 0x16 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Location", 0x04, 0x17 }, /* supported since v2.5 */ + { "MeetingStatus", 0x04, 0x18 }, /* supported since v2.5 */ + { "Organizer_Email", 0x04, 0x19 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Organizer_Name", 0x04, 0x1a }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence", 0x04, 0x1b }, /* supported since v2.5 */ + { "Recurrence_Type", 0x04, 0x1c }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_Until", 0x04, 0x1d }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_Occurrences", 0x04, 0x1e }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_Interval", 0x04, 0x1f }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_DayOfWeek", 0x04, 0x20 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_DayOfMonth", 0x04, 0x21 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_WeekOfMonth", 0x04, 0x22 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Recurrence_MonthOfYear", 0x04, 0x23 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Reminder", 0x04, 0x24 }, /* supported since v2.5 */ + { "Sensitivity", 0x04, 0x25 }, /* supported since v2.5 */ + { "Subject", 0x04, 0x26 }, /* supported since v2.5 */ + { "StartTime", 0x04, 0x27 }, /* supported since v2.5 */ + { "UID", 0x04, 0x28 }, /* supported since v2.5 */ + { "Attendee_Status", 0x04, 0x29 }, /* corrected in libwbxml 0.11.0, supported since v12.0 */ + { "Attendee_Type", 0x04, 0x2a }, /* corrected in libwbxml 0.11.0, supported since v12.0 */ + { "DisallowNewTimeProposal",0x04, 0x33 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "ResponseRequested", 0x04, 0x34 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "AppointmentReplyTime", 0x04, 0x35 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "ResponseType", 0x04, 0x36 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "CalendarType", 0x04, 0x37 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "IsLeapMonth", 0x04, 0x38 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "FirstDayOfWeek", 0x04, 0x39 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "OnlineMeetingConfLink", 0x04, 0x3a }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "OnlineMeetingExternalLink",0x04, 0x3b }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + + /* Code Page: Move (since v2.5 and r1.0) */ + { "MoveItems", 0x05, 0x05 }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Move", 0x05, 0x06 }, /* since r1.0 */ + { "SrcMsgId", 0x05, 0x07 }, /* since r1.0 */ + { "SrcFldId", 0x05, 0x08 }, /* since r1.0 */ + { "DstFldId", 0x05, 0x09 }, /* since r1.0 */ + { "Response", 0x05, 0x0a }, /* since r1.0 */ + { "Status", 0x05, 0x0b }, /* since r1.0 */ + { "DstMsgId", 0x05, 0x0c }, /* since r1.0 */ + + /* Code Page: ItemEstimate (since v2.5 and r1.0) */ + { "GetItemEstimate", 0x06, 0x05 }, /* since r1.0 */ + { "Version", 0x06, 0x06 }, /* r8.0: only supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "Collections", 0x06, 0x07 }, /* since r1.0 */ + { "Collection", 0x06, 0x08 }, /* since r1.0 */ + { "Class", 0x06, 0x09 }, /* r8.0: only supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "CollectionId", 0x06, 0x0a }, /* since r1.0 */ + { "DateTime", 0x06, 0x0b }, /* r8.0: only supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "Estimate", 0x06, 0x0c }, /* since r1.0 */ + { "Response", 0x06, 0x0d }, /* since r1.0 */ + { "Status", 0x06, 0x0e }, /* since r1.0 */ + + /* Code Page: FolderHierarchy (since v2.5 and r1.0) */ + { "Folders", 0x07, 0x05 }, /* not defined in r8.0 but in r1.0 */ + { "Folder", 0x07, 0x06 }, /* not defined in r8.0 but in r1.0 */ + { "DisplayName", 0x07, 0x07 }, /* since r1.0 */ + { "ServerId", 0x07, 0x08 }, /* since r1.0 */ + { "ParentId", 0x07, 0x09 }, /* since r1.0 */ + { "Type", 0x07, 0x0a }, /* since r1.0 */ + { "Response", 0x07, 0x0b }, /* not defined in r8.0 but in r1.0 */ + { "Status", 0x07, 0x0c }, /* since r1.0 */ + { "ContentClass", 0x07, 0x0d }, /* not defined in r8.0 but in r1.0 */ + { "Changes", 0x07, 0x0e }, /* since r1.0 */ + { "Add", 0x07, 0x0f }, /* since r1.0 */ + { "Delete", 0x07, 0x10 }, /* since r1.0 */ + { "Update", 0x07, 0x11 }, /* since r1.0 */ + { "SyncKey", 0x07, 0x12 }, /* since r1.0 */ + { "FolderCreate", 0x07, 0x13 }, /* since r1.0 */ + { "FolderDelete", 0x07, 0x14 }, /* since r1.0 */ + { "FolderUpdate", 0x07, 0x15 }, /* since r1.0 */ + { "FolderSync", 0x07, 0x16 }, /* since r1.0 */ + { "Count", 0x07, 0x17 }, /* since r1.0 */ + { "Version", 0x07, 0x18 }, /* not defined in r8.0 but in r1.0 */ + + /* Code Page: MeetingResponse (since v2.5 and r1.0) */ + { "CalendarId", 0x08, 0x05 }, /* changed in r8.0, r1.0: CallID */ + { "CollectionId", 0x08, 0x06 }, /* since r1.0 */ + { "MeetingResponse", 0x08, 0x07 }, /* since r1.0 */ + { "RequestId", 0x08, 0x08 }, /* changed in r8.0, r1.0: ReqId */ + { "Request", 0x08, 0x09 }, /* since r1.0 */ + { "Result", 0x08, 0x0a }, /* since r1.0 */ + { "Status", 0x08, 0x0b }, /* since r1.0 */ + { "UserResponse", 0x08, 0x0c }, /* since r1.0 */ + { "Version", 0x08, 0x0d }, /* not defined in r8.0 but in r1.0 */ + { "InstanceId", 0x08, 0x0e }, /* since r8.0? */ + + /* Code Page: Tasks (since v2.5 and r1.0) */ + { "Body", 0x09, 0x05 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "BodySize", 0x09, 0x06 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "BodyTruncated", 0x09, 0x07 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "Categories", 0x09, 0x08 }, /* supported since v2.5 */ + { "Category", 0x09, 0x09 }, /* supported since v2.5 */ + { "Complete", 0x09, 0x0a }, /* supported since v2.5 */ + { "DateCompleted", 0x09, 0x0b }, /* supported since v2.5 */ + { "DueDate", 0x09, 0x0c }, /* supported since v2.5 */ + { "UTCDueDate", 0x09, 0x0d }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Importance", 0x09, 0x0e }, /* supported since v2.5 */ + { "Recurrence", 0x09, 0x0f }, /* supported since v2.5 */ + { "Recurrence_Type", 0x09, 0x10 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceType */ + { "Recurrence_Start", 0x09, 0x11 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceStart */ + { "Recurrence_Until", 0x09, 0x12 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceUntil */ + { "Recurrence_Occurrences", 0x09, 0x13 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceOccurrences */ + { "Recurrence_Interval", 0x09, 0x14 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceInterval */ + { "Recurrence_DayOfMonth", 0x09, 0x15 }, /* supported since v2.5, changed in r8.0, r1.0: RecurrenceDayOfMonth */ + { "Recurrence_DayOfWeek", 0x09, 0x16 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceDayOfWeek */ + { "Recurrence_DayOfMonth", 0x09, 0x15 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceDayOfMonth */ + { "Recurrence_WeekOfMonth", 0x09, 0x17 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceWeekOfMonth */ + { "Recurrence_MonthOfYear", 0x09, 0x18 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceMonthOfYear */ + { "Recurrence_Regenerate", 0x09, 0x19 }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceRegenerate */ + { "Recurrence_DeadOccur", 0x09, 0x1a }, /* corrected in libwbxml 0.11.0, supported since v2.5, changed in r8.0, r1.0: RecurrenceDeadOccour */ + { "ReminderSet", 0x09, 0x1b }, /* supported since v2.5 */ + { "ReminderTime", 0x09, 0x1c }, /* supported since v2.5 */ + { "Sensitivity", 0x09, 0x1d }, /* supported since v2.5 */ + { "StartDate", 0x09, 0x1e }, /* supported since v2.5 */ + { "UTCStartDate", 0x09, 0x1f }, /* corrected in libwbxml 0.11.0, supported since v2.5 */ + { "Subject", 0x09, 0x20 }, /* supported since v2.5 */ + { "CompressedRTF", 0x09, 0x21 }, /* corrected in libwbxml 0.11.0, not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { "OrdinalDate", 0x09, 0x22 }, /* supported since v12.0 */ + { "SubOrdinalDate", 0x09, 0x23 }, /* supported since v12.0 */ + { "CalendarType", 0x09, 0x24 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "IsLeapMonth", 0x09, 0x25 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "FirstDayOfWeek", 0x09, 0x26 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + + /* Code Page: ResolveRecipients (since v2.5 and r1.0) */ + { "ResolveRecipients", 0x0a, 0x05 }, /* since r1.0 */ + { "Response", 0x0a, 0x06 }, /* since r1.0 */ + { "Status", 0x0a, 0x07 }, /* since r1.0 */ + { "Type", 0x0a, 0x08 }, /* since r1.0 */ + { "Recipient", 0x0a, 0x09 }, /* since r1.0 */ + { "DisplayName", 0x0a, 0x0a }, /* since r1.0 */ + { "EmailAddress", 0x0a, 0x0b }, /* since r1.0 */ + { "Certificates", 0x0a, 0x0c }, /* since r1.0 */ + { "Certificate", 0x0a, 0x0d }, /* since r1.0 */ + { "MiniCertificate", 0x0a, 0x0e }, /* since r1.0 */ + { "Options", 0x0a, 0x0f }, /* since r1.0 */ + { "To", 0x0a, 0x10 }, /* since r1.0 */ + { "CertificateRetrieval", 0x0a, 0x11 }, /* since r1.0 */ + { "RecipientCount", 0x0a, 0x12 }, /* since r1.0 */ + { "MaxCertificates", 0x0a, 0x13 }, /* since r1.0 */ + { "MaxAmbiguousRecipients", 0x0a, 0x14 }, /* since r1.0 */ + { "CertificateCount", 0x0a, 0x15 }, /* since r1.0 */ + { "Availability", 0x0a, 0x16 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "StartTime", 0x0a, 0x17 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "EndTime", 0x0a, 0x18 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "MergedFreeBusy", 0x0a, 0x19 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "Picture", 0x0a, 0x1a }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "MaxSize", 0x0a, 0x1b }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "Data", 0x0a, 0x1c }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "MaxPictures", 0x0a, 0x1d }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + + /* Code Page: ValidateCert (since v2.5 and r1.0) */ + { "ValidateCert", 0x0b, 0x05 }, /* since r1.0 */ + { "Certificates", 0x0b, 0x06 }, /* since r1.0 */ + { "Certificate", 0x0b, 0x07 }, /* since r1.0 */ + { "CertificateChain", 0x0b, 0x08 }, /* since r1.0 */ + { "CheckCRL", 0x0b, 0x09 }, /* since r1.0 */ + { "Status", 0x0b, 0x0a }, /* since r1.0 */ + + /* Code Page: Contacts2 (since v2.5 and r1.0) */ + { "CustomerId", 0x0c, 0x05 }, /* since r1.0 */ + { "GovernmentId", 0x0c, 0x06 }, /* since r1.0 */ + { "IMAddress", 0x0c, 0x07 }, /* since r1.0 */ + { "IMAddress2", 0x0c, 0x08 }, /* since r1.0 */ + { "IMAddress3", 0x0c, 0x09 }, /* since r1.0 */ + { "ManagerName", 0x0c, 0x0a }, /* since r1.0 */ + { "CompanyMainPhone", 0x0c, 0x0b }, /* since r1.0 */ + { "AccountName", 0x0c, 0x0c }, /* since r1.0 */ + { "NickName", 0x0c, 0x0d }, /* since r1.0 */ + { "MMS", 0x0c, 0x0e }, /* since r1.0 */ + + /* Code Page: Ping (since v2.5 and r1.0) */ + { "Ping", 0x0d, 0x05 }, /* since r1.0 */ + { "AutdState", 0x0d, 0x06 }, /* not used by protocol */ + { "Status", 0x0d, 0x07 }, /* since r1.0 */ + { "HeartbeatInterval", 0x0d, 0x08 }, /* since r1.0 */ + { "Folders", 0x0d, 0x09 }, /* since r1.0 */ + { "Folder", 0x0d, 0x0a }, /* since r1.0 */ + { "Id", 0x0d, 0x0b }, /* since r1.0 */ + { "Class", 0x0d, 0x0c }, /* since r1.0 */ + { "MaxFolders", 0x0d, 0x0d }, /* since r1.0 */ + + /* Code Page: Provision (since v2.5 and r1.0) */ + { "Provision", 0x0e, 0x05 }, /* supported since v2.5 */ + { "Policies", 0x0e, 0x06 }, /* supported since v2.5 */ + { "Policy", 0x0e, 0x07 }, /* supported since v2.5 */ + { "PolicyType", 0x0e, 0x08 }, /* supported since v2.5 */ + { "PolicyKey", 0x0e, 0x09 }, /* supported since v2.5 */ + { "Data", 0x0e, 0x0a }, /* supported since v2.5 */ + { "Status", 0x0e, 0x0b }, /* supported since v2.5 */ + { "RemoteWipe", 0x0e, 0x0c }, /* supported since v2.5 */ + { "EASProvisionDoc", 0x0e, 0x0d }, /* supported since v12.0 */ + { "DevicePasswordEnabled", 0x0e, 0x0e }, /* supported since v12.0 */ + { "AlphanumericDevicePasswordRequired", 0x0e, 0x0f }, /* supported since v12.0 */ + { "DeviceEncryptionEnabled", 0x0e, 0x10 }, /* r1.0: supported since v12.0 */ + { "RequireStorageCardEncryption", 0x0e, 0x10 }, /* r1.0: supported by v2.0 and v2.5 */ + { "PasswordRecoveryEnabled", 0x0e, 0x11 }, /* supported since v12.0 */ + { "DocumentBrowseEnabled", 0x0e, 0x12 }, /* supported since v12.0, not defined in r8.0 but in r1.0 */ + { "AttachmentsEnabled", 0x0e, 0x13 }, /* supported since v12.0 */ + { "MinDevicePasswordLength", 0x0e, 0x14 }, /* supported since v12.0 */ + { "MaxInactivityTimeDeviceLock", 0x0e, 0x15 }, /* supported since v12.0 */ + { "MaxDevicePasswordFailedAttempts", 0x0e, 0x16 }, /* supported since v12.0 */ + { "MaxAttachmentSize", 0x0e, 0x17 }, /* supported since v12.0 */ + { "AllowSimpleDevicePassword", 0x0e, 0x18 }, /* supported since v12.0 */ + { "DevicePasswordExpiration", 0x0e, 0x19 }, /* supported since v12.0 */ + { "DevicePasswordHistory", 0x0e, 0x1a }, /* supported since v12.0 */ + { "AllowStorageCard", 0x0e, 0x1b }, /* supported since v12.1 */ + { "AllowCamera", 0x0e, 0x1c }, /* supported by v2.0 and v2.5 */ + { "RequireDeviceEncryption", 0x0e, 0x1d }, /* supported by v2.0 and v2.5 */ + { "AllowUnsignedApplications", 0x0e, 0x1e }, /* supported by v2.0 and v2.5 */ + { "AllowUnsignedInstallationPackages", 0x0e, 0x1f }, /* supported by v2.0 and v2.5 */ + { "MinDevicePasswordComplexCharacters", 0x0e, 0x20 }, /* supported by v2.0 and v2.5 */ + { "AllowWiFi", 0x0e, 0x21 }, /* supported by v2.0 and v2.5 */ + { "AllowTextMessaging", 0x0e, 0x22 }, /* supported by v2.0 and v2.5 */ + { "AllowPOPIMAPEmail", 0x0e, 0x23 }, /* supported by v2.0 and v2.5 */ + { "AllowBluetooth", 0x0e, 0x24 }, /* supported by v2.0 and v2.5 */ + { "AllowIrDA", 0x0e, 0x25 }, /* supported by v2.0 and v2.5 */ + { "RequireManualSyncWhenRoaming", 0x0e, 0x26 }, /* supported by v2.0 and v2.5 */ + { "AllowDesktopSync", 0x0e, 0x27 }, /* supported by v2.0 and v2.5 */ + { "MaxCalendarAgeFilter", 0x0e, 0x28 }, /* supported by v2.0 and v2.5 */ + { "AllowHTMLEmail", 0x0e, 0x29 }, /* supported by v2.0 and v2.5 */ + { "MaxEmailAgeFilter", 0x0e, 0x2a }, /* supported by v2.0 and v2.5 */ + { "MaxEmailBodyTruncationSize", 0x0e, 0x2b }, /* supported by v2.0 and v2.5 */ + { "MaxEmailHTMLBodyTruncationSize", 0x0e, 0x2c }, /* supported by v2.0 and v2.5 */ + { "RequireSignedSMIMEMessages", 0x0e, 0x2d }, /* supported by v2.0 and v2.5 */ + { "RequireEncryptedSMIMEMessages", 0x0e, 0x2e }, /* supported by v2.0 and v2.5 */ + { "RequireSignedSMIMEAlgorithm", 0x0e, 0x2f }, /* supported by v2.0 and v2.5 */ + { "RequireEncryptionSMIMEAlgorithm", 0x0e, 0x30 }, /* supported by v2.0 and v2.5 */ + { "AllowSMIMEEncryptionAlgorithmNegotiation", 0x0e, 0x31 }, /* supported by v2.0 and v2.5 */ + { "AllowSMIMESoftCerts", 0x0e, 0x32 }, /* supported by v2.0 and v2.5 */ + { "AllowBrowser", 0x0e, 0x33 }, /* supported by v2.0 and v2.5 */ + { "AllowConsumerEmail", 0x0e, 0x34 }, /* supported by v2.0 and v2.5 */ + { "AllowRemoteDesktop", 0x0e, 0x35 }, /* supported by v2.0 and v2.5 */ + { "AllowInternetSharing", 0x0e, 0x36 }, /* supported by v2.0 and v2.5 */ + { "UnapprovedInROMApplicationList", 0x0e, 0x37 }, /* supported by v2.0 and v2.5 */ + { "ApplicationName", 0x0e, 0x38 }, /* supported by v2.0 and v2.5 */ + { "ApprovedApplicationList", 0x0e, 0x39 }, /* supported by v2.0 and v2.5 */ + { "Hash", 0x0e, 0x3a }, /* supported by v2.0 and v2.5 */ + + /* Code Page: Search (since v2.5 and r1.0) */ + /* Token 0x06 and 0x16 are not supported. */ + { "Search", 0x0f, 0x05 }, /* supported since v2.5 */ + { "Store", 0x0f, 0x07 }, /* supported since v2.5 */ + { "Name", 0x0f, 0x08 }, /* supported since v2.5 */ + { "Query", 0x0f, 0x09 }, /* supported since v2.5 */ + { "Options", 0x0f, 0x0a }, /* supported since v2.5 */ + { "Range", 0x0f, 0x0b }, /* supported since v2.5 */ + { "Status", 0x0f, 0x0c }, /* supported since v2.5 */ + { "Response", 0x0f, 0x0d }, /* supported since v2.5 */ + { "Result", 0x0f, 0x0e }, /* supported since v2.5 */ + { "Properties", 0x0f, 0x0f }, /* supported since v2.5 */ + { "Total", 0x0f, 0x10 }, /* supported since v2.5 */ + { "EqualTo", 0x0f, 0x11 }, /* supported since v12.0 */ + { "Value", 0x0f, 0x12 }, /* supported since v12.0 */ + { "And", 0x0f, 0x13 }, /* supported since v12.0 */ + { "Or", 0x0f, 0x14 }, /* supported since v12.0, r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "FreeText", 0x0f, 0x15 }, /* supported since v12.0 */ + { "DeepTraversal", 0x0f, 0x17 }, /* supported since v12.0 */ + { "LongId", 0x0f, 0x18 }, /* supported since v12.0 */ + { "RebuildResults", 0x0f, 0x19 }, /* supported since v12.0 */ + { "LessThan", 0x0f, 0x1a }, /* supported since v12.0 */ + { "GreaterThan", 0x0f, 0x1b }, /* supported since v12.0 */ + { "Schema", 0x0f, 0x1c }, /* supported since v12.0, r8.0: not defined in r8.0 but in r1.0 */ + { "Supported", 0x0f, 0x1d }, /* supported since v12.0, r8.0: not defined in r8.0 but in r1.0 */ + { "UserName", 0x0f, 0x1e }, /* since 8.0? */ + { "Password", 0x0f, 0x1f }, /* since 8.0? */ + { "ConversationId", 0x0f, 0x20, WBXML_TAG_OPTION_BINARY }, /* since 8.0? */ + { "Picture", 0x0f, 0x21 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "MaxSize", 0x0f, 0x22 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "MaxPictures", 0x0f, 0x23 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + + /* Code Page: GAL (since v2.5 and r1.0) */ + { "DisplayName", 0x10, 0x05 }, /* since r1.0 */ + { "Phone", 0x10, 0x06 }, /* since r1.0 */ + { "Office", 0x10, 0x07 }, /* since r1.0 */ + { "Title", 0x10, 0x08 }, /* since r1.0 */ + { "Company", 0x10, 0x09 }, /* since r1.0 */ + { "Alias", 0x10, 0x0a }, /* since r1.0 */ + { "FirstName", 0x10, 0x0b }, /* since r1.0 */ + { "LastName", 0x10, 0x0c }, /* since r1.0 */ + { "HomePhone", 0x10, 0x0d }, /* since r1.0 */ + { "MobilePhone", 0x10, 0x0e }, /* since r1.0 */ + { "EmailAddress", 0x10, 0x0f }, /* since r1.0 */ + { "Picture", 0x10, 0x10 }, /* not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "Status", 0x10, 0x11 }, /* not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "Data", 0x10, 0x12 }, /* not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + + /* Code Page: AirSyncBase (since v12.0 and r1.0) */ + { "BodyPreference", 0x11, 0x05 }, /* since r1.0 */ + { "Type", 0x11, 0x06 }, /* since r1.0 */ + { "TruncationSize", 0x11, 0x07 }, /* since r1.0 */ + { "AllOrNone", 0x11, 0x08 }, /* since r1.0 */ + { "Body", 0x11, 0x0a }, /* since r1.0 */ + { "Data", 0x11, 0x0b }, /* since r1.0 */ + { "EstimatedDataSize", 0x11, 0x0c }, /* since r1.0 */ + { "Truncated", 0x11, 0x0d }, /* since r1.0 */ + { "Attachments", 0x11, 0x0e }, /* since r1.0 */ + { "Attachment", 0x11, 0x0f }, /* since r1.0 */ + { "DisplayName", 0x11, 0x10 }, /* since r1.0 */ + { "FileReference", 0x11, 0x11 }, /* since r1.0 */ + { "Method", 0x11, 0x12 }, /* since r1.0 */ + { "ContentId", 0x11, 0x13 }, /* since r1.0 */ + { "ContentLocation", 0x11, 0x14 }, /* r8.0: not used */ + { "IsInline", 0x11, 0x15 }, /* since r1.0 */ + { "NativeBodyType", 0x11, 0x16 }, /* since r1.0 */ + { "ContentType", 0x11, 0x17 }, /* since r1.0 */ + { "Preview", 0x11, 0x18 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "BodyPartPreference", 0x11, 0x19 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 or 14 */ + { "BodyPart", 0x11, 0x1a }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 or 14 */ + { "Status", 0x11, 0x1b }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 or 14 */ + + /* Code Page: Settings (since v12.1 and r1.0) */ + { "Settings", 0x12, 0x05 }, /* since r1.0 */ + { "Status", 0x12, 0x06 }, /* since r1.0 */ + { "Get", 0x12, 0x07 }, /* since r1.0 */ + { "Set", 0x12, 0x08 }, /* since r1.0 */ + { "Oof", 0x12, 0x09 }, /* since r1.0 */ + { "OofState", 0x12, 0x0a }, /* since r1.0 */ + { "StartTime", 0x12, 0x0b }, /* since r1.0 */ + { "EndTime", 0x12, 0x0c }, /* since r1.0 */ + { "OofMessage", 0x12, 0x0d }, /* since r1.0 */ + { "AppliesToInternal", 0x12, 0x0e }, /* since r1.0 */ + { "AppliesToExternalKnown", 0x12, 0x0f }, /* since r1.0 */ + { "AppliesToExternalUnknown", 0x12, 0x10 }, /* since r1.0 */ + { "Enabled", 0x12, 0x11 }, /* since r1.0 */ + { "ReplyMessage", 0x12, 0x12 }, /* since r1.0 */ + { "BodyType", 0x12, 0x13 }, /* since r1.0 */ + { "DevicePassword", 0x12, 0x14 }, /* since r1.0 */ + { "Password", 0x12, 0x15 }, /* since r1.0 */ + { "DeviceInformation", 0x12, 0x16 }, /* since r1.0 */ + { "Model", 0x12, 0x17 }, /* since r1.0 */ + { "IMEI", 0x12, 0x18 }, /* since r1.0 */ + { "FriendlyName", 0x12, 0x19 }, /* since r1.0 */ + { "OS", 0x12, 0x1a }, /* since r1.0 */ + { "OSLanguage", 0x12, 0x1b }, /* since r1.0 */ + { "PhoneNumber", 0x12, 0x1c }, /* since r1.0 */ + { "UserInformation", 0x12, 0x1d }, /* since r1.0 */ + { "EmailAddresses", 0x12, 0x1e }, /* since r1.0 */ + { "SmtpAddress", 0x12, 0x1f }, /* since r1.0 */ + { "UserAgent", 0x12, 0x20 }, /* since r8.0? */ + { "EnableOutboundSMS", 0x12, 0x21 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "MobileOperator", 0x12, 0x22 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "PrimarySmtpAddress", 0x12, 0x23 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "Accounts", 0x12, 0x24 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "Account", 0x12, 0x25 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "AccountId", 0x12, 0x26 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "AccountName", 0x12, 0x27 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "UserDisplayName", 0x12, 0x28 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "SendDisabled", 0x12, 0x29 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "ihsManagementInformation", 0x12, 0x2b }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + + /* Code Page: DocumentLibrary (since v12.1 and r1.0) */ + { "LinkId", 0x13, 0x05 }, /* since r1.0 */ + { "DisplayName", 0x13, 0x06 }, /* since r1.0 */ + { "IsFolder", 0x13, 0x07 }, /* since r1.0 */ + { "CreationDate", 0x13, 0x08 }, /* since r1.0 */ + { "LastModifiedDate", 0x13, 0x09 }, /* since r1.0 */ + { "IsHidden", 0x13, 0x0a }, /* since r1.0 */ + { "ContentLength", 0x13, 0x0b }, /* since r1.0 */ + { "ContentType", 0x13, 0x0c }, /* since r1.0 */ + + /* Code Page: ItemOperations (since v12.1 and r1.0) */ + { "ItemOperations", 0x14, 0x05 }, /* since r1.0 */ + { "Fetch", 0x14, 0x06 }, /* since r1.0 */ + { "Store", 0x14, 0x07 }, /* since r1.0 */ + { "Options", 0x14, 0x08 }, /* since r1.0 */ + { "Range", 0x14, 0x09 }, /* since r1.0 */ + { "Total", 0x14, 0x0a }, /* since r1.0 */ + { "Properties", 0x14, 0x0b }, /* since r1.0 */ + { "Data", 0x14, 0x0c }, /* since r1.0 */ + { "Status", 0x14, 0x0d }, /* since r1.0 */ + { "Response", 0x14, 0x0e }, /* since r1.0 */ + { "Version", 0x14, 0x0f }, /* since r1.0 */ + { "Schema", 0x14, 0x10 }, /* since r1.0 */ + { "Part", 0x14, 0x11 }, /* since r1.0 */ + { "EmptyFolderContents", 0x14, 0x12 }, /* since r1.0 */ + { "DeleteSubFolders", 0x14, 0x13 }, /* since r1.0 */ + { "UserName", 0x14, 0x14 }, /* since r8.0? */ + { "Password", 0x14, 0x15 }, /* since r8.0? */ + { "Move", 0x14, 0x16 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "DstFldId", 0x14, 0x17 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "ConversationId", 0x14, 0x18, WBXML_TAG_OPTION_BINARY }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "MoveAlways", 0x14, 0x19 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + + /* Code Page: ComposeMail (since v14.0 and r8.0?) */ + /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "SendMail", 0x15, 0x05 }, /* since r8.0? */ + { "SmartForward", 0x15, 0x06 }, /* since r8.0? */ + { "SmartReply", 0x15, 0x07 }, /* since r8.0? */ + { "SaveInSentItems", 0x15, 0x08 }, /* since r8.0? */ + { "ReplaceMime", 0x15, 0x09 }, /* since r8.0? */ + { "Source", 0x15, 0x0b }, /* since r8.0? */ + { "FolderId", 0x15, 0x0c }, /* since r8.0? */ + { "ItemId", 0x15, 0x0d }, /* since r8.0? */ + { "LongId", 0x15, 0x0e }, /* since r8.0? */ + { "InstanceId", 0x15, 0x0f }, /* since r8.0? */ + { "MIME", 0x15, 0x10, WBXML_TAG_OPTION_BINARY }, /* since r8.0? */ + { "ClientId", 0x15, 0x11 }, /* since r8.0? */ + { "Status", 0x15, 0x12 }, /* since r8.0? */ + { "AccountId", 0x15, 0x13 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + + /* Code Page: Email2 (since v14.0 and r8.0?) */ + /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "UmCallerID", 0x16, 0x05 }, /* since r8.0? */ + { "UmUserNotes", 0x16, 0x06 }, /* since r8.0? */ + { "UmAttDuration", 0x16, 0x07 }, /* since r8.0? */ + { "UmAttOrder", 0x16, 0x08 }, /* since r8.0? */ + { "ConversationId", 0x16, 0x09, WBXML_TAG_OPTION_BINARY }, /* since r8.0? */ + { "ConversationIndex", 0x16, 0x0a, WBXML_TAG_OPTION_BINARY }, /* since r8.0? */ + { "LastVerbExecuted", 0x16, 0x0b }, /* since r8.0? */ + { "LastVerbExecutionTime", 0x16, 0x0c }, /* since r8.0? */ + { "ReceivedAsBcc", 0x16, 0x0d }, /* since r8.0? */ + { "Sender", 0x16, 0x0e }, /* since r8.0? */ + { "CalendarType", 0x16, 0x0f }, /* since r8.0? */ + { "IsLeapMonth", 0x16, 0x10 }, /* since r8.0? */ + { "AccountId", 0x16, 0x11 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "FirstDayOfWeek", 0x16, 0x12 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "MeetingMessageType", 0x16, 0x13 }, /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + + /* Code Page: Notes (since v14.0 and r8.0?) */ + /* r8.0: not supported when the MS-ASProtocolVersion header is set to 12.1 */ + { "Subject", 0x17, 0x05 }, /* since r8.0? */ + { "MessageClass", 0x17, 0x06 }, /* since r8.0? */ + { "LastModifiedDate", 0x17, 0x07 }, /* since r8.0? */ + { "Categories", 0x17, 0x08 }, /* since r8.0? */ + { "Category", 0x17, 0x09 }, /* since r8.0? */ + + /* Code Page: RightsManagement (since r8.0?) */ + /* r8.0: not supported when the MS-ASProtocolVersion header is set to 14.0 or 12.1 */ + { "RightsManagementSupport",0x18, 0x05 }, /* since r8.0? */ + { "RightsManagementTemplates",0x18, 0x06 }, /* since r8.0? */ + { "RightsManagementTemplate",0x18, 0x07 }, /* since r8.0? */ + { "RightsManagementLicense",0x18, 0x08 }, /* since r8.0? */ + { "EditAllowed", 0x18, 0x09 }, /* since r8.0? */ + { "ReplyAllowed", 0x18, 0x0a }, /* since r8.0? */ + { "ReplyAllAllowed", 0x18, 0x0b }, /* since r8.0? */ + { "ForwardAllowed", 0x18, 0x0c }, /* since r8.0? */ + { "ModifyRecipientsAllowed",0x18, 0x0d }, /* since r8.0? */ + { "ExtractAllowed", 0x18, 0x0e }, /* since r8.0? */ + { "PrintAllowed", 0x18, 0x0f }, /* since r8.0? */ + { "ExportAllowed", 0x18, 0x10 }, /* since r8.0? */ + { "ProgrammaticAccessAllowed",0x18, 0x11 }, /* since r8.0? */ + { "RMOwner", 0x18, 0x12 }, /* since r8.0? */ + { "ContentExpiryDate", 0x18, 0x13 }, /* since r8.0? */ + { "TemplateID", 0x18, 0x14 }, /* since r8.0? */ + { "TemplateName", 0x18, 0x15 }, /* since r8.0? */ + { "TemplateDescription", 0x18, 0x16 }, /* since r8.0? */ + { "ContentOwner", 0x18, 0x17 }, /* since r8.0? */ + { "RemoveRightsManagementDistribution",0x18, 0x18 }, /* since r8.0? */ + + { NULL, 0x00, 0x00 } +}; + +const WBXMLAttrEntry sv_airsync_attr_table[] = { + { "Version", "1.1", 0x03, 0x05 }, /* not defined in r8.0 but in r1.0, supported by v2.5, v12.0 and v12.1 */ + { NULL, NULL, 0x00, 0x00 } +}; + +/* NOTE: + * These namespace names differ from the Microsoft-assigned namespaces. The + * reason for the difference is that the Microsoft-assigned names are not + * valid URI's and hence produce warning messages when processed by some + * libraries. The mapping is as follows: + * + * Microsoft Ours + * --------- ---- + * AirSync: http://synce.org/formats/airsync_wm5/airsync + * Contacts: http://synce.org/formats/airsync_wm5/contacts + * Email: http://synce.org/formats/airsync_wm5/email + * AirNotify: http://synce.org/formats/airsync_wm5/airnotify + * Calendar: http://synce.org/formats/airsync_wm5/calendar + * Move: http://synce.org/formats/airsync_wm5/move + * ItemEstimate: http://synce.org/formats/airsync_wm5/itemestimate + * FolderHierarchy: http://synce.org/formats/airsync_wm5/folderhierarchy + * MeetingResponse: http://synce.org/formats/airsync_wm5/meetingresponse + * Tasks: http://synce.org/formats/airsync_wm5/tasks + * ResolveRecipients: http://synce.org/formats/airsync_wm5/resolverecipients + * ValidateCert: http://synce.org/formats/airsync_wm5/validatecert + * Contacts2: http://synce.org/formats/airsync_wm5/contacts2 + * Ping: http://synce.org/formats/airsync_wm5/ping + * Provision: http://synce.org/formats/airsync_wm5/provision + * Search: http://synce.org/formats/airsync_wm5/search + * Gal: http://synce.org/formats/airsync_wm5/gal + * AirSyncBase: http://synce.org/formats/airsync_wm5/airsyncbase + * Settings: http://synce.org/formats/airsync_wm5/settings + * DocumentLibrary: http://synce.org/formats/airsync_wm5/documentlibrary + * ItemOperations: http://synce.org/formats/airsync_wm5/itemoperations + * ComposeMail: http://synce.org/formats/airsync_wm5/composemail + * Email2: http://synce.org/formats/airsync_wm5/email2 + * Notes: http://synce.org/formats/airsync_wm5/notes + * RightsManagement: http://synce.org/formats/airsync_wm5/rightsmanagement + * + */ +const WBXMLNameSpaceEntry sv_airsync_ns_table[] = { + { "http://synce.org/formats/airsync_wm5/airsync", 0x00 }, /**< Code Page 0 */ + { "http://synce.org/formats/airsync_wm5/contacts", 0x01 }, /**< Code Page 1 */ + { "http://synce.org/formats/airsync_wm5/email", 0x02 }, /**< Code Page 2 */ + { "http://synce.org/formats/airsync_wm5/airnotify", 0x03 }, /**< Code Page 3 */ + { "http://synce.org/formats/airsync_wm5/calendar", 0x04 }, /**< Code Page 4 */ + { "http://synce.org/formats/airsync_wm5/move", 0x05 }, /**< Code Page 5 */ + { "http://synce.org/formats/airsync_wm5/itemestimate", 0x06 }, /**< Code Page 6 */ + { "http://synce.org/formats/airsync_wm5/folderhierarchy", 0x07 }, /**< Code Page 7 */ + { "http://synce.org/formats/airsync_wm5/meetingresponse", 0x08 }, /**< Code Page 8 */ + { "http://synce.org/formats/airsync_wm5/tasks", 0x09 }, /**< Code Page 9 */ + { "http://synce.org/formats/airsync_wm5/resolverecipients", 0x0a }, /**< Code Page 10 */ + { "http://synce.org/formats/airsync_wm5/validatecert", 0x0b }, /**< Code Page 11 */ + { "http://synce.org/formats/airsync_wm5/contacts2", 0x0c }, /**< Code Page 12 */ + { "http://synce.org/formats/airsync_wm5/ping", 0x0d }, /**< Code Page 13 */ + { "http://synce.org/formats/airsync_wm5/provision", 0x0e }, /**< Code Page 14 */ + { "http://synce.org/formats/airsync_wm5/search", 0x0f }, /**< Code Page 15 */ + { "http://synce.org/formats/airsync_wm5/gal", 0x10 }, /**< Code Page 16 */ + { "http://synce.org/formats/airsync_wm5/airsyncbase", 0x11 }, /**< Code Page 17 */ + { "http://synce.org/formats/airsync_wm5/settings", 0x12 }, /**< Code Page 18 */ + { "http://synce.org/formats/airsync_wm5/documentlibrary", 0x13 }, /**< Code Page 19 */ + { "http://synce.org/formats/airsync_wm5/itemoperations", 0x14 }, /**< Code Page 20 */ + { "http://synce.org/formats/airsync_wm5/composemail", 0x15 }, /**< Code Page 21 */ + { "http://synce.org/formats/airsync_wm5/email2", 0x16 }, /**< Code Page 22 */ + { "http://synce.org/formats/airsync_wm5/notes", 0x17 }, /**< Code Page 23 */ + { "http://synce.org/formats/airsync_wm5/rightsmanagement", 0x18 }, /**< Code Page 24 */ + { NULL, 0x00 } +}; + +const WBXMLNameSpaceEntry sv_activesync_ns_table[] = { + { "AirSync:", 0x00 }, /**< Code Page 0 */ + { "Contacts:", 0x01 }, /**< Code Page 1 */ + { "Email:", 0x02 }, /**< Code Page 2 */ + { "AirNotify:", 0x03 }, /**< Code Page 3 */ + { "Calendar:", 0x04 }, /**< Code Page 4 */ + { "Move:", 0x05 }, /**< Code Page 5 */ + { "GetItemEstimate:", 0x06 }, /**< Code Page 6 */ + { "FolderHierarchy:", 0x07 }, /**< Code Page 7 */ + { "MeetingResponse:", 0x08 }, /**< Code Page 8 */ + { "Tasks:", 0x09 }, /**< Code Page 9 */ + { "ResolveRecipients:", 0x0a }, /**< Code Page 10 */ + { "ValidateCert:", 0x0b }, /**< Code Page 11 */ + { "Contacts2:", 0x0c }, /**< Code Page 12 */ + { "Ping:", 0x0d }, /**< Code Page 13 */ + { "Provision:", 0x0e }, /**< Code Page 14 */ + { "Search:", 0x0f }, /**< Code Page 15 */ + { "Gal:", 0x10 }, /**< Code Page 16 */ + { "AirSyncBase:", 0x11 }, /**< Code Page 17 */ + { "Settings:", 0x12 }, /**< Code Page 18 */ + { "DocumentLibrary:", 0x13 }, /**< Code Page 19 */ + { "ItemOperations:", 0x14 }, /**< Code Page 20 */ + { "ComposeMail:", 0x15 }, /**< Code Page 21 */ + { "Email2:", 0x16 }, /**< Code Page 22 */ + { "Notes:", 0x17 }, /**< Code Page 23 */ + { "RightsManagement:", 0x18 }, /**< Code Page 24 */ + { NULL, 0x00 } +}; + +#endif /* WBXML_SUPPORT_AIRSYNC */ + + +#if defined( WBXML_SUPPORT_CONML ) + +/************************************************* + * Nokia ConML + * + * This is no official markup language from Nokia. + * It is used for example by Nokia PC Suite to install software. + */ + +const WBXMLTagEntry sv_conml_tag_table[] = { + /* Code Page: "ConML" */ + { "All", 0x00, 0x05 }, + { "Application", 0x00, 0x06 }, + { "Applications", 0x00, 0x07 }, + { "Unknown_0x08", 0x00, 0x08 }, + { "Cancel", 0x00, 0x09 }, + { "Complete", 0x00, 0x0a }, + { "ConML", 0x00, 0x0b }, + { "Data", 0x00, 0x0c }, + /* Candidates from SyncML: + DataType * + DefaultValue + Delete + Description * + DevID * + */ + { "Unknown_0x0d", 0x00, 0x0d }, + { "Unknown_0x0e", 0x00, 0x0e }, + { "Unknown_0x0f", 0x00, 0x0f }, + { "DeviceInfo", 0x00, 0x10 }, + /* Candidates from SyncML: + DevTyp + */ + { "Unknown_0x11", 0x00, 0x11 }, + { "Drives", 0x00, 0x12 }, + { "Execute", 0x00, 0x13 }, + /* Candidates from SyncML: + Final + */ + { "Unknown_0x14", 0x00, 0x14 }, + { "Unknown_0x15", 0x00, 0x15 }, + { "Unknown_0x16", 0x00, 0x16 }, + { "GetDataSize", 0x00, 0x17 }, + { "GetStatus", 0x00, 0x18 }, + { "HasFiles", 0x00, 0x19 }, + { "ID", 0x00, 0x1a }, + { "IncType", 0x00, 0x1b }, + { "Install", 0x00, 0x1c }, + { "InstParams", 0x00, 0x1d }, + { "ListInstalledApps", 0x00, 0x1f }, + /* Candidates from SyncML: + MaxMsgSize + */ + { "Unknown_0x20", 0x00, 0x20 }, + { "MaxObjectSize", 0x00, 0x21 }, + { "Modified", 0x00, 0x22 }, + { "MoreData", 0x00, 0x23 }, + /* The content of the element Name is originally encoded as opaque data. + The mobiles accepts the element data also as a normal string. + Therefore the data will be encoded as a string. + If there is a requirement for the original behavior + then it is necessary to add some code to wbxml_encoder.c. + */ + { "Name", 0x00, 0x24 }, + { "PackageInfo", 0x00, 0x25 }, + { "Param", 0x00, 0x26 }, + { "PartialType", 0x00, 0x27 }, + { "Progress", 0x00, 0x28 }, + { "Reboot", 0x00, 0x29 }, + /* Candidates from SyncML: + Replace + RespURI + */ + { "Unknown_0x2a", 0x00, 0x2a }, + { "Unknown_0x2b", 0x00, 0x2b }, + { "Results", 0x00, 0x2c }, + /* Candidates from SyncML: + Search + Sequence + SessionID + SftDel + Source + SourceRef + */ + { "Unknown_0x2d", 0x00, 0x2d }, + { "Unknown_0x2e", 0x00, 0x2e }, + { "Unknown_0x2f", 0x00, 0x2f }, + { "Unknown_0x30", 0x00, 0x30 }, + { "Status", 0x00, 0x31 }, + /* Candidates from SyncML: + Target + TargetRef + */ + { "Unknown_0x32", 0x00, 0x32 }, + { "Unknown_0x33", 0x00, 0x33 }, + { "Unknown_0x34", 0x00, 0x34 }, + { "Task", 0x00, 0x35 }, + /* Candidates from SyncML: + Time + TStamp + Title + */ + { "Unknown_0x36", 0x00, 0x36 }, + { "Type", 0x00, 0x37 }, + { "UID", 0x00, 0x38 }, + { "UnInstall", 0x00, 0x39 }, + /* Candidates from SyncML: + ValEnum + */ + { "Unknown_0x3a", 0x00, 0x3a }, + { "Unknown_0x3b", 0x00, 0x3b }, + { "Value", 0x00, 0x3c }, + { "Version", 0x00, 0x3d }, + { NULL, 0x00, 0x00 } +}; + +#endif /* WBXML_SUPPORT_CONML */ + + +/****************************** + * Main Table + */ + +const WBXMLLangEntry sv_table_entry[] = { +#if defined( WBXML_SUPPORT_WML ) +#ifdef WBXML_TABLES_SEPARATE_WML_VERSIONS + { WBXML_LANG_WML10, &sv_wml10_public_id, sv_wml10_tag_table, NULL, sv_wml10_attr_table, sv_wml10_attr_value_table, NULL }, + { WBXML_LANG_WML11, &sv_wml11_public_id, sv_wml11_tag_table, NULL, sv_wml11_attr_table, sv_wml11_attr_value_table, NULL }, + { WBXML_LANG_WML12, &sv_wml12_public_id, sv_wml12_tag_table, NULL, sv_wml12_attr_table, sv_wml12_attr_value_table, NULL }, +#else /* WBXML_TABLES_SEPARATE_WML_VERSIONS */ + { WBXML_LANG_WML10, &sv_wml10_public_id, sv_wml13_tag_table, NULL, sv_wml13_attr_table, sv_wml13_attr_value_table, NULL }, + { WBXML_LANG_WML11, &sv_wml11_public_id, sv_wml13_tag_table, NULL, sv_wml13_attr_table, sv_wml13_attr_value_table, NULL }, + { WBXML_LANG_WML12, &sv_wml12_public_id, sv_wml13_tag_table, NULL, sv_wml13_attr_table, sv_wml13_attr_value_table, NULL }, +#endif /* WBXML_TABLES_SEPARATE_WML_VERSIONS */ + { WBXML_LANG_WML13, &sv_wml13_public_id, sv_wml13_tag_table, NULL, sv_wml13_attr_table, sv_wml13_attr_value_table, NULL }, +#endif /* WBXML_SUPPORT_WML */ + +#if defined( WBXML_SUPPORT_WTA ) + { WBXML_LANG_WTA10, &sv_wta10_public_id, sv_wta10_tag_table, NULL, sv_wta10_attr_table, NULL, NULL }, + { WBXML_LANG_WTAWML12, &sv_wtawml12_public_id, sv_wtawml12_tag_table, NULL, sv_wtawml12_attr_table, sv_wtawml12_attr_value_table, NULL }, + { WBXML_LANG_CHANNEL11, &sv_channel11_public_id, sv_channel11_tag_table, NULL, sv_channel11_attr_table, NULL, NULL }, + { WBXML_LANG_CHANNEL12, &sv_channel12_public_id, sv_channel12_tag_table, NULL, sv_channel12_attr_table, NULL, NULL }, +#endif /* WBXML_SUPPORT_WTA */ + +#if defined( WBXML_SUPPORT_SI ) + { WBXML_LANG_SI10, &sv_si10_public_id, sv_si10_tag_table, NULL, sv_si10_attr_table, sv_si10_attr_value_table, NULL }, +#endif /* WBXML_SUPPORT_SI */ + +#if defined( WBXML_SUPPORT_SL ) + { WBXML_LANG_SL10, &sv_sl10_public_id, sv_sl10_tag_table, NULL, sv_sl10_attr_table, sv_sl10_attr_value_table, NULL }, +#endif /* WBXML_SUPPORT_SL */ + +#if defined( WBXML_SUPPORT_CO ) + { WBXML_LANG_CO10, &sv_co10_public_id, sv_co10_tag_table, NULL, sv_co10_attr_table, sv_co10_attr_value_table, NULL }, +#endif /* WBXML_SUPPORT_CO */ + +#if defined( WBXML_SUPPORT_PROV ) + { WBXML_LANG_PROV10, &sv_prov10_public_id, sv_prov10_tag_table, NULL, sv_prov10_attr_table, sv_prov10_attr_value_table, NULL }, +#endif /* WBXML_SUPPORT_PROV */ + +#if defined( WBXML_SUPPORT_EMN ) + { WBXML_LANG_EMN10, &sv_emn10_public_id, sv_emn10_tag_table, NULL, sv_emn10_attr_table, sv_emn10_attr_value_table, NULL }, +#endif /* WBXML_SUPPORT_EMN */ + +#if defined( WBXML_SUPPORT_DRMREL ) + { WBXML_LANG_DRMREL10, &sv_drmrel10_public_id, sv_drmrel10_tag_table, NULL, sv_drmrel10_attr_table, sv_drmrel10_attr_value_table, NULL }, +#endif /* WBXML_SUPPORT_DRMREL */ + +#if defined( WBXML_SUPPORT_OTA_SETTINGS ) + { WBXML_LANG_OTA_SETTINGS, &sv_ota_settings_public_id, sv_ota_settings_tag_table, NULL, sv_ota_settings_attr_table, NULL, NULL }, +#endif /* WBXML_SUPPORT_OTA_SETTINGS */ + +#if defined( WBXML_SUPPORT_SYNCML ) + /* SyncML 1.2 */ + { WBXML_LANG_SYNCML_SYNCML12, &sv_syncml_syncml12_public_id, sv_syncml_syncml12_tag_table, sv_syncml_syncml12_ns_table, NULL, NULL, NULL }, + { WBXML_LANG_SYNCML_DEVINF12, &sv_syncml_devinf12_public_id, sv_syncml_devinf12_tag_table, sv_syncml_devinf12_ns_table, NULL, NULL, NULL }, + { WBXML_LANG_SYNCML_METINF12, &sv_syncml_metinf12_public_id, sv_syncml_metinf12_tag_table, NULL, NULL, NULL, NULL }, + { WBXML_LANG_SYNCML_DMDDF12, &sv_syncml_dmddf12_public_id, sv_syncml_dmddf12_tag_table, sv_syncml_dmddf12_ns_table, NULL, NULL, NULL }, + + /* SyncML 1.1 */ + { WBXML_LANG_SYNCML_SYNCML11, &sv_syncml_syncml11_public_id, sv_syncml_syncml11_tag_table, sv_syncml_syncml11_ns_table, NULL, NULL, NULL }, + { WBXML_LANG_SYNCML_DEVINF11, &sv_syncml_devinf11_public_id, sv_syncml_devinf11_tag_table, sv_syncml_devinf11_ns_table, NULL, NULL, NULL }, + { WBXML_LANG_SYNCML_METINF11, &sv_syncml_metinf11_public_id, sv_syncml_metinf11_tag_table, NULL, NULL, NULL, NULL }, + + /** @todo Check if Tag Tables are exactly with SyncML 1.0 */ + { WBXML_LANG_SYNCML_SYNCML10, &sv_syncml_syncml10_public_id, sv_syncml_syncml11_tag_table, sv_syncml_syncml10_ns_table, NULL, NULL, NULL }, + { WBXML_LANG_SYNCML_DEVINF10, &sv_syncml_devinf10_public_id, sv_syncml_devinf11_tag_table, sv_syncml_devinf11_ns_table, NULL, NULL, NULL }, +#endif /* WBXML_SUPPORT_SYNCML */ + +#if defined( WBXML_SUPPORT_WV ) + { WBXML_LANG_WV_CSP11, &sv_wv_csp11_public_id, sv_wv_csp_tag_table, NULL, sv_wv_csp_attr_table, NULL, sv_wv_csp_ext_table }, + { WBXML_LANG_WV_CSP12, &sv_wv_csp12_public_id, sv_wv_csp_tag_table, NULL, sv_wv_csp_attr_table, NULL, sv_wv_csp_ext_table }, +#endif /* WBXML_SUPPORT_WV */ + +#if defined( WBXML_SUPPORT_AIRSYNC ) + { WBXML_LANG_AIRSYNC, &sv_airsync_public_id, sv_airsync_tag_table, sv_airsync_ns_table, sv_airsync_attr_table, NULL, NULL }, + { WBXML_LANG_ACTIVESYNC, &sv_activesync_public_id, sv_airsync_tag_table, sv_activesync_ns_table, sv_airsync_attr_table, NULL, NULL }, +#endif /* WBXML_SUPPORT_AIRSYNC */ + +#if defined( WBXML_SUPPORT_CONML ) + { WBXML_LANG_CONML, &sv_conml_public_id, sv_conml_tag_table, NULL, NULL, NULL, NULL }, +#endif /* WBXML_SUPPORT_CONML */ + + { WBXML_LANG_UNKNOWN, NULL, NULL, NULL, NULL, NULL, NULL } +}; + + +/****************************** + * Public Functions + */ + +/* Exported function to return pointer to WBXML Languages Main Table */ +WBXML_DECLARE(const WBXMLLangEntry *) wbxml_tables_get_main(void) +{ + return sv_table_entry; +} + + +WBXML_DECLARE(const WBXMLLangEntry *) wbxml_tables_get_table(WBXMLLanguage lang) +{ + const WBXMLLangEntry *main_table = NULL; + WB_ULONG index = 0; + + /* Get main tables array*/ + if ((lang == WBXML_LANG_UNKNOWN) || ((main_table = wbxml_tables_get_main()) == NULL)) + return NULL; + + /* Search language table */ + while (main_table[index].langID != WBXML_LANG_UNKNOWN) { + if (main_table[index].langID == lang) + return &main_table[index]; + index++; + } + + return NULL; +} + + +WBXML_DECLARE(const WBXMLLangEntry *) wbxml_tables_search_table(const WBXMLLangEntry *main_table, + const WB_UTINY *public_id, + const WB_UTINY *system_id, + const WB_UTINY *root) +{ + WB_ULONG index; + const WB_UTINY *sep = NULL; + + if (main_table == NULL) + return NULL; + + /* Search by XML Public ID */ + if (public_id != NULL) { + index = 0; + + while (main_table[index].publicID != NULL) { + if (main_table[index].publicID->xmlPublicID && WBXML_STRCASECMP(main_table[index].publicID->xmlPublicID, public_id) == 0) + return &main_table[index]; + index++; + } + } + + /* Search by XML System ID */ + if (system_id != NULL) { + index = 0; + + while (main_table[index].publicID != NULL) { + if (main_table[index].publicID->xmlDTD && WBXML_STRCMP(main_table[index].publicID->xmlDTD, system_id) == 0) + return &main_table[index]; + index++; + } + } + + /* Search by XML Root Element */ + if (root != NULL) { + index = 0; + + /* table scan for matching namespace element */ + sep = (WB_UTINY *)strrchr((const WB_TINY *) root, WBXML_NAMESPACE_SEPARATOR); + if (sep != NULL) { + /* There is a namespace (from root to sep). */ + while (main_table[index].publicID != NULL) { + /* It is only possible to evaluate the first entry in the table + * because the second code page has often no unique name space name. + * Example: SyncML Meta Information => syncml:metinf + */ + if (main_table[index].nsTable != NULL && + main_table[index].nsTable[0].xmlNameSpace && + WBXML_STRNCASECMP(main_table[index].nsTable[0].xmlNameSpace, root, WBXML_STRLEN(main_table[index].nsTable[0].xmlNameSpace)) == 0) + return &main_table[index]; + index++; + } + } + + /* table scan for matching root element */ + while (main_table[index].publicID != NULL) { + if (main_table[index].publicID->xmlRootElt && WBXML_STRCMP(main_table[index].publicID->xmlRootElt, root) == 0) + return &main_table[index]; + index++; + } + } + + return NULL; +} + + +WBXML_DECLARE(WB_ULONG) wbxml_tables_get_wbxml_publicid(const WBXMLLangEntry *main_table, WBXMLLanguage lang_id) +{ + WB_ULONG i = 0; + + if (main_table == NULL) + return WBXML_PUBLIC_ID_UNKNOWN; + + while (main_table[i].langID != WBXML_LANG_UNKNOWN) { + if (main_table[i].langID == lang_id) { + if (main_table[i].publicID != NULL) + return main_table[i].publicID->wbxmlPublicID; + else + return WBXML_PUBLIC_ID_UNKNOWN; + } + i++; + } + + return WBXML_PUBLIC_ID_UNKNOWN; +} + + +WBXML_DECLARE(const WBXMLTagEntry *) wbxml_tables_get_tag_from_xml(const WBXMLLangEntry *lang_table, + const int cur_code_page, + const WB_UTINY *xml_name) +{ + WB_ULONG i; + WB_BOOL found_current = FALSE; + + if ((lang_table == NULL) || (lang_table->tagTable == NULL) || (xml_name == NULL)) + return NULL; + + /* First off, try to find it in the current code page, if provided */ + for (i = 0; cur_code_page >= 0 && lang_table->tagTable[i].xmlName != NULL; i++) { + const WBXMLTagEntry *entry = &lang_table->tagTable[i]; + + if (entry->wbxmlCodePage == cur_code_page) { + found_current = TRUE; + + if (WBXML_STRCMP(entry->xmlName, xml_name) == 0) + return entry; + } else { + if (found_current) + break; + } + } + + /* Then try all others */ + for (i = 0; lang_table->tagTable[i].xmlName != NULL; i++) { + const WBXMLTagEntry *entry = &lang_table->tagTable[i]; + + /* We've already searched the current code page */ + if (cur_code_page >= 0 && entry->wbxmlCodePage == cur_code_page) + continue; + + if (WBXML_STRCMP(entry->xmlName, xml_name) == 0) + return entry; + } + + return NULL; +} + + +WBXML_DECLARE(const WBXMLAttrEntry *) wbxml_tables_get_attr_from_xml(const WBXMLLangEntry *lang_table, + WB_UTINY *xml_name, + WB_UTINY *xml_value, + WB_UTINY **value_left) +{ + WB_ULONG i = 0; + WB_ULONG found_index = 0, found_comp = 0; + WB_BOOL found = FALSE; + + if ((lang_table == NULL) || (lang_table->attrTable == NULL) || (xml_name == NULL)) + return NULL; + + if (value_left != NULL) + *value_left = xml_value; + + /* Iterate in Attribute Table */ + while (lang_table->attrTable[i].xmlName != NULL) { + /* Search for Attribute Name */ + if (WBXML_STRCMP(lang_table->attrTable[i].xmlName, xml_name) == 0) + { + if (lang_table->attrTable[i].xmlValue == NULL) { + /* This is the token with a NULL Attribute Value */ + if (xml_value == NULL) { + /* Well, we got it */ + return &(lang_table->attrTable[i]); + } + else { + if (!found) { + /* We haven't found yet a better Attribute Token */ + found = TRUE; + found_index = i; + } + + /* Else: We already have found a better Attribute Token, so let's forget this one */ + } + } + else { + /* Check the Attribute Value */ + if (xml_value != NULL) + { + if (WBXML_STRCMP(lang_table->attrTable[i].xmlValue, xml_value) == 0) + { + /* We have found the EXACT Attribute Name / Value pair we are searching, well done boy */ + if (value_left != NULL) + *value_left = NULL; + + return &(lang_table->attrTable[i]); + } + else { + if ((WBXML_STRLEN(lang_table->attrTable[i].xmlValue) < WBXML_STRLEN(xml_value)) && + (found_comp < WBXML_STRLEN(lang_table->attrTable[i].xmlValue)) && + (WBXML_STRNCMP(lang_table->attrTable[i].xmlValue, xml_value, WBXML_STRLEN(lang_table->attrTable[i].xmlValue)) == 0)) + { + /* We have found a better Attribute Value */ + found = TRUE; + found_index = i; + found_comp = WBXML_STRLEN(lang_table->attrTable[i].xmlValue); + } + } + } + + /* Else: We are searching for the Attribute Token with a NULL Attribute Value associated, so forget this one */ + } + } + i++; + } + + /* Attribute Name / Value pair not found, but an entry with this Attribute Name, + * and (maybe) start of this Attribute Value was found */ + if (found) { + if (value_left != NULL) + *value_left = xml_value + found_comp; + + return &(lang_table->attrTable[found_index]); + } + + /* Attribute Name NOT found */ + return NULL; +} + + +WBXML_DECLARE(const WBXMLExtValueEntry *) wbxml_tables_get_ext_from_xml(const WBXMLLangEntry *lang_table, + WB_UTINY *xml_value) +{ + WB_ULONG i = 0; + + if ((lang_table == NULL) || (lang_table->extValueTable == NULL) || (xml_value == NULL)) + return NULL; + + while (lang_table->extValueTable[i].xmlName != NULL) { + if (WBXML_STRCMP(lang_table->extValueTable[i].xmlName, xml_value) == 0) + return &(lang_table->extValueTable[i]); + i++; + } + + return NULL; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_tables_contains_attr_value_from_xml(const WBXMLLangEntry *lang_table, + WB_UTINY *xml_value) +{ + WB_ULONG i = 0; + + if ((lang_table == NULL) || (lang_table->attrValueTable == NULL) || (xml_value == NULL)) + return FALSE; + + while (lang_table->attrValueTable[i].xmlName != NULL) + { + /* Is this Attribute Value contained in this XML Buffer ? */ + if (WBXML_STRSTR(xml_value, lang_table->attrValueTable[i].xmlName) != NULL) + return TRUE; + + i++; + } + + return FALSE; +} + + +WBXML_DECLARE(const WB_TINY *) wbxml_tables_get_xmlns(const WBXMLNameSpaceEntry *ns_table, WB_UTINY code_page) +{ + WB_ULONG i = 0; + + if (ns_table == NULL) + return NULL; + + while (ns_table[i].xmlNameSpace != NULL) + { + if (ns_table[i].wbxmlCodePage == code_page) + return ns_table[i].xmlNameSpace; + + i++; + } + + return NULL; +} + +WBXML_DECLARE(WB_UTINY) wbxml_tables_get_code_page(const WBXMLNameSpaceEntry *ns_table, const WB_TINY* xmlns) +{ + WB_ULONG i = 0; + + if (ns_table == NULL) + return 0; + + while (ns_table[i].xmlNameSpace != NULL) + { + if (strcmp(ns_table[i].xmlNameSpace, xmlns) == 0) + return ns_table[i].wbxmlCodePage; + + i++; + } + + return 0; +} + diff --git a/src/wbxml_tables.h b/src/wbxml_tables.h new file mode 100644 index 0000000..2e4d8c0 --- /dev/null +++ b/src/wbxml_tables.h @@ -0,0 +1,346 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2009-2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_tables.h + * @ingroup wbxml_tables + * + * @author Aymerick Jehanne + * @date 02/03/17 + * + * @brief WBXML Tables + */ + +#ifndef WBXML_TABLES_H +#define WBXML_TABLES_H + +#include "wbxml.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_tables + * @{ + */ + +/**************************************************** + * WBXML Public IDs (http://www.wapforum.org/wina) + */ + +#define WBXML_PUBLIC_ID_UNKNOWN 0x01 + +/* WAP */ +#define WBXML_PUBLIC_ID_WML10 0x02 +#define WBXML_PUBLIC_ID_WTA10 0x03 +#define WBXML_PUBLIC_ID_WML11 0x04 +#define WBXML_PUBLIC_ID_SI10 0x05 +#define WBXML_PUBLIC_ID_SL10 0x06 +#define WBXML_PUBLIC_ID_CO10 0x07 +#define WBXML_PUBLIC_ID_CHANNEL11 0x08 +#define WBXML_PUBLIC_ID_WML12 0x09 +#define WBXML_PUBLIC_ID_WML13 0x0A +#define WBXML_PUBLIC_ID_PROV10 0x0B +#define WBXML_PUBLIC_ID_WTAWML12 0x0C +#define WBXML_PUBLIC_ID_CHANNEL12 WBXML_PUBLIC_ID_UNKNOWN /**< I don't understand what is the Channel1.2 WBXML Public ID */ +#define WBXML_PUBLIC_ID_EMN10 0x0D +#define WBXML_PUBLIC_ID_DRMREL10 0x0E + +#define XML_PUBLIC_ID_WML10 "-//WAPFORUM//DTD WML 1.0//EN" +#define XML_PUBLIC_ID_WTA10 "-//WAPFORUM//DTD WTA 1.0//EN" +#define XML_PUBLIC_ID_WML11 "-//WAPFORUM//DTD WML 1.1//EN" +#define XML_PUBLIC_ID_SI10 "-//WAPFORUM//DTD SI 1.0//EN" +#define XML_PUBLIC_ID_SL10 "-//WAPFORUM//DTD SL 1.0//EN" +#define XML_PUBLIC_ID_CO10 "-//WAPFORUM//DTD CO 1.0//EN" +#define XML_PUBLIC_ID_CHANNEL11 "-//WAPFORUM//DTD CHANNEL 1.1//EN" +#define XML_PUBLIC_ID_WML12 "-//WAPFORUM//DTD WML 1.2//EN" +#define XML_PUBLIC_ID_WML13 "-//WAPFORUM//DTD WML 1.3//EN" +#define XML_PUBLIC_ID_PROV10 "-//WAPFORUM//DTD PROV 1.0//EN" +#define XML_PUBLIC_ID_WTAWML12 "-//WAPFORUM//DTD WTA-WML 1.2//EN" +#define XML_PUBLIC_ID_CHANNEL12 "-//WAPFORUM//DTD CHANNEL 1.2//EN" +#define XML_PUBLIC_ID_EMN10 "-//WAPFORUM//DTD EMN 1.0//EN" +#define XML_PUBLIC_ID_DRMREL10 "-//OMA//DTD DRMREL 1.0//EN" + +/* Ericsson/Nokia OTA Settings v7.0 */ +#define WBXML_PUBLIC_ID_OTA_SETTINGS WBXML_PUBLIC_ID_UNKNOWN +#define XML_PUBLIC_ID_OTA_SETTINGS NULL /* No XML Public ID defined */ + +/* SyncML 1.0 */ +#define WBXML_PUBLIC_ID_SYNCML_SYNCML10 0x0FD1 +#define WBXML_PUBLIC_ID_SYNCML_DEVINF10 0x0FD2 +#define WBXML_PUBLIC_ID_SYNCML_METINF10 WBXML_PUBLIC_ID_UNKNOWN /* No WBXML PublicID defined for SyncML Meta Info */ + +#define XML_PUBLIC_ID_SYNCML_SYNCML10 "-//SYNCML//DTD SyncML 1.0//EN" +#define XML_PUBLIC_ID_SYNCML_DEVINF10 "-//SYNCML//DTD DevInf 1.0//EN" +#define XML_PUBLIC_ID_SYNCML_METINF10 "-//SYNCML//DTD MetInf 1.0//EN" + +/* SyncML 1.1 */ +#define WBXML_PUBLIC_ID_SYNCML_SYNCML11 0x0FD3 +#define WBXML_PUBLIC_ID_SYNCML_DEVINF11 0x0FD4 +#define WBXML_PUBLIC_ID_SYNCML_METINF11 WBXML_PUBLIC_ID_UNKNOWN /* No WBXML PublicID defined for SyncML Meta Info */ + +#define XML_PUBLIC_ID_SYNCML_SYNCML11 "-//SYNCML//DTD SyncML 1.1//EN" +#define XML_PUBLIC_ID_SYNCML_DEVINF11 "-//SYNCML//DTD DevInf 1.1//EN" +#define XML_PUBLIC_ID_SYNCML_METINF11 "-//SYNCML//DTD MetInf 1.1//EN" + +/* SyncML 1.2 */ +#define WBXML_PUBLIC_ID_SYNCML_SYNCML12 0x1201 +#define WBXML_PUBLIC_ID_SYNCML_METINF12 0x1202 +#define WBXML_PUBLIC_ID_SYNCML_DEVINF12 0x1203 +#define WBXML_PUBLIC_ID_SYNCML_DMDDF12 WBXML_PUBLIC_ID_UNKNOWN /* No WBXML PublicID defined for OMA DM DDF */ + +#define XML_PUBLIC_ID_SYNCML_SYNCML12 "-//SYNCML//DTD SyncML 1.2//EN" +#define XML_PUBLIC_ID_SYNCML_DEVINF12 "-//SYNCML//DTD DevInf 1.2//EN" +#define XML_PUBLIC_ID_SYNCML_METINF12 "-//SYNCML//DTD MetInf 1.2//EN" +#define XML_PUBLIC_ID_SYNCML_DMDDF12 "-//OMA//DTD-DM-DDF 1.2//EN" + +/* OMA Wireless Village CSP 1.1 / 1.2 - @todo Check for CSP 1.0 */ +#define WBXML_PUBLIC_ID_WV_CSP11 0x10 +#define WBXML_PUBLIC_ID_WV_CSP12 WBXML_PUBLIC_ID_UNKNOWN + +#define XML_PUBLIC_ID_WV_CSP11 "-//OMA//DTD WV-CSP 1.1//EN" /**< @todo Also defined as "-//WIRELESSVILLAGE//DTD CSP 1.1//EN" (so choose one) */ +#define XML_PUBLIC_ID_WV_CSP12 "-//OMA//DTD WV-CSP 1.2//EN" + +/* Microsoft AirSync */ +#define WBXML_PUBLIC_ID_AIRSYNC WBXML_PUBLIC_ID_UNKNOWN +#define XML_PUBLIC_ID_AIRSYNC "-//AIRSYNC//DTD AirSync//EN" + +#define WBXML_PUBLIC_ID_ACTIVESYNC WBXML_PUBLIC_ID_UNKNOWN +#define XML_PUBLIC_ID_ACTIVESYNC "-//MICROSOFT//DTD ActiveSync//EN" + +/* Nokia ConML */ +#define WBXML_PUBLIC_ID_CONML 0x8F +#define XML_PUBLIC_ID_CONML "-//CONML//DTD ConML//EN" + +/**************************************************** + * WBXML Encoding options + */ + +#define WBXML_TAG_OPTION_UNKNOWN 0x0 +#define WBXML_TAG_OPTION_BINARY 0x1 +#define WBXML_TAG_OPTION_OPAQUE 0x2 +#define WBXML_TAG_OPTION_CDATA 0x4 + +/* Example: CDATA|OPAQUE + * => XML: + * => WBXML: create opaque encoding + */ + +/**************************************************** + * WBXML Tables Structures + */ + +/** + * @brief WBXML Public ID structure + */ +typedef struct WBXMLPublicIDEntry_s +{ + WB_ULONG wbxmlPublicID; /**< WBXML Public ID */ + const WB_TINY *xmlPublicID; /**< XML Public ID */ + const WB_TINY *xmlRootElt; /**< XML Root Element */ + const WB_TINY *xmlDTD; /**< XML DTD */ + +} WBXMLPublicIDEntry; + + +/** + * @brief WBXML Application Token structure: Tag token + * The options are used to optionally define the + * handling of content. + */ +typedef struct WBXMLTagEntry_s +{ + const WB_TINY *xmlName; /**< XML Tag Name */ + WB_UTINY wbxmlCodePage; /**< WBXML Code Page */ + WB_UTINY wbxmlToken; /**< WBXML Tag Token */ + WB_ULONG options; /**< (WB)XML (Encoding) Options (optional bit mask)*/ +} WBXMLTagEntry; + + +/** + * @brief Name Space + * @note For SyncML, where a WBXML Code Page is associated to an XML Name Space + */ +typedef struct WBXMLNameSpaceEntry_s +{ + const WB_TINY *xmlNameSpace; /**< XML Name Space */ + WB_UTINY wbxmlCodePage; /**< WBXML Code Page */ +} WBXMLNameSpaceEntry; + + +/** + * @brief WBXML Application Token structure: Attribute token + */ +typedef struct WBXMLAttrEntry_s +{ + const WB_TINY *xmlName; /**< XML Attribute Name */ + const WB_TINY *xmlValue; /**< XML Attribute Value (may be NULL) */ + WB_UTINY wbxmlCodePage; /**< WBXML Code Page */ + WB_UTINY wbxmlToken; /**< WBXML Attribute Token */ +} WBXMLAttrEntry; + + +/** + * @brief WBXML Application Token structure: Attribute Value token + */ +typedef struct WBXMLAttrValueEntry_s +{ + const WB_TINY *xmlName; /**< XML Attribute Value */ + WB_UTINY wbxmlCodePage; /**< WBXML Code Page */ + WB_UTINY wbxmlToken; /**< WBXML Attribute Value Token */ +} WBXMLAttrValueEntry; + + +/** + * @brief WBXML Application Token structure: Extension Value token + * @note For Wireless-Village, the content can be tokenized with Extension Tokens + */ +typedef struct WBXMLExtValueEntry_s +{ + const WB_TINY *xmlName; /**< XML Extension Value */ + WB_UTINY wbxmlToken; /**< WBXML Extension Value Token */ +} WBXMLExtValueEntry; + + +/** + * @brief Language structure + */ +typedef struct WBXMLLangEntry_s +{ + WBXMLLanguage langID; /**< Language ID */ + const WBXMLPublicIDEntry *publicID; /**< Public ID */ + const WBXMLTagEntry *tagTable; /**< Tags Table */ + const WBXMLNameSpaceEntry *nsTable; /**< NameSpaces Table */ + const WBXMLAttrEntry *attrTable; /**< Attributes Table*/ + const WBXMLAttrValueEntry *attrValueTable; /**< Attributes Values Table */ + const WBXMLExtValueEntry *extValueTable; /**< Extensions Values Table */ +} WBXMLLangEntry; + + +/** + * @brief Get Main Table + * @return The main array of WBXML Language Tables + */ +WBXML_DECLARE(const WBXMLLangEntry *) wbxml_tables_get_main(void); + +/** + * @brief Get a Language Table + * @param lang Language to get + * @return The Language Table, or NULL if unknown Language + */ +WBXML_DECLARE(const WBXMLLangEntry *) wbxml_tables_get_table(WBXMLLanguage lang); + +/** + * @brief Search for a Language Table + * @param main_table Main Table Array to search in + * @param public_id The Public ID to search [can be NULL] + * @param system_id The System ID to search [can be NULL] + * @param root The Root Element to search [can be NULL] + * @return The Language Table found, or NULL if none found + * @note This function try to find the correct Language Table thanks to the XML Public ID, then (if not found) by + * the XML System ID, and finally (if not found) by the Root XML Element + */ +WBXML_DECLARE(const WBXMLLangEntry *) wbxml_tables_search_table(const WBXMLLangEntry *main_table, + const WB_UTINY *public_id, + const WB_UTINY *system_id, + const WB_UTINY *root); + +/** + * @brief Get the WBXML Public ID corresponding to given WBXML Language + * @param main_table The Main Languages Table to search in + * @param lang_id The Language ID + * @return The WBXML Public ID (can be WBXML_PUBLIC_ID_UNKNOWN if Language doesn't have one, or if Language not found) +*/ +WBXML_DECLARE(WB_ULONG) wbxml_tables_get_wbxml_publicid(const WBXMLLangEntry *main_table, + WBXMLLanguage lang_id); + +/** + * @brief Search for a Tag Entry in Language Table, given the XML Name of the Tag + * @param lang_table The Language Table to search in + * @param cur_code_page The current code page so that it can be searched first, or -1 to start from the first one. + * @param xml_name The XML Name of the Tag to search + * @return The Tag Entry of this XML Name in Language Table, or NULL if not found + */ +WBXML_DECLARE(const WBXMLTagEntry *) wbxml_tables_get_tag_from_xml(const WBXMLLangEntry *lang_table, + const int cur_code_page, + const WB_UTINY *xml_name); + +/** + * @brief Search for an Attribute Entry in Language Table, given the XML Name and Value of the Attribute + * @param lang_table The Language Table to search in + * @param xml_name The XML Name of the Attribute to search + * @param xml_value The XML Value of the Attribute to search + * @param value_left Is the WBXMLAttrEntry returned EXACTLY the Attribute we are searching ? (ie: is the Attribute Value + * found matching the one we were looking for ?). If Yes, then this is NULL. If not, then this is the + * attribute value part that we still have to encode. + * @return The Attribute Entry of this XML Attribute Name in Language Table, or NULL if not found + * @note Has the Attribut Value can be expressed in many ways in WBXML, this function is focused on + * searching for the ATTRIBUTE NAME ! + * Thus, when Attribute Name is found in Table, we search for an Entry with the same Attribute Name / Attribute Value + * pair. If found the 'value_left' parameter is set to NULL. If not, we still return an Entry matching the Attribute Name, + * but the 'value_left' parameter is the Attribute Value part that is not included in the Attrbute Token. + */ +WBXML_DECLARE(const WBXMLAttrEntry *) wbxml_tables_get_attr_from_xml(const WBXMLLangEntry *lang_table, + WB_UTINY *xml_name, + WB_UTINY *xml_value, + WB_UTINY **value_left); + +/** + * @brief Search for an Extension Token Entry in Language Table, given the XML Value of the Extension + * @param lang_table The Language Table to search in + * @param xml_value The XML Value of the Extension to search + * @return The Extension Token Entry of this XML Value in Language Table, or NULL if not found + */ +WBXML_DECLARE(const WBXMLExtValueEntry *) wbxml_tables_get_ext_from_xml(const WBXMLLangEntry *lang_table, + WB_UTINY *xml_value); + +/** + * @brief Check if an XML Attribute Value contains at least one Attribute Value defined in Language Attribute Values Table + * @param lang_table The Language Table to search in + * @param xml_value The XML Attribute Value to check + * @return TRUE if this value contains an Attribute Value, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_tables_contains_attr_value_from_xml(const WBXMLLangEntry *lang_table, + WB_UTINY *xml_value); + +/** + * @brief Get an XML NameSpace, given a WBXML Code Page + * @param ns_table The NameSpace Table + * @param code_page The WBXML Code Page + * @return The XML NameSpace, or NULL if not found + */ +WBXML_DECLARE(const WB_TINY *) wbxml_tables_get_xmlns(const WBXMLNameSpaceEntry *ns_table, + WB_UTINY code_page); + +WBXML_DECLARE(WB_UTINY) wbxml_tables_get_code_page(const WBXMLNameSpaceEntry *ns_table, + const WB_TINY* xmlns); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_TABLES_H */ diff --git a/src/wbxml_tree.c b/src/wbxml_tree.c new file mode 100644 index 0000000..e30da74 --- /dev/null +++ b/src/wbxml_tree.c @@ -0,0 +1,1362 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2008-2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_tree.c + * @ingroup wbxml_tree + * + * @author Aymerick Jehanne + * @date 03/02/18 + * + * @brief WBXML Tree + */ + +#include "wbxml_config_internals.h" +#include "wbxml_tree.h" +#include "wbxml_log.h" +#include "wbxml_parser.h" +#include "wbxml_encoder.h" +#include "wbxml_tree_clb_xml.h" +#include "wbxml_tree_clb_wbxml.h" +#include "wbxml_internals.h" + +/*************************************************** + * Public Functions + */ + +WBXML_DECLARE(WBXMLError) wbxml_tree_from_wbxml(WB_UTINY *wbxml, + WB_ULONG wbxml_len, + WBXMLLanguage lang, + WBXMLCharsetMIBEnum charset, + WBXMLTree **tree) +{ + WBXMLParser *wbxml_parser = NULL; + WB_LONG error_index = 0; + WBXMLTreeClbCtx wbxml_tree_clb_ctx; + WBXMLError ret = WBXML_OK; + WBXMLContentHandler wbxml_tree_content_handler = + { + wbxml_tree_clb_wbxml_start_document, + wbxml_tree_clb_wbxml_end_document, + wbxml_tree_clb_wbxml_start_element, + wbxml_tree_clb_wbxml_end_element, + wbxml_tree_clb_wbxml_characters, + wbxml_tree_clb_wbxml_pi + }; + + if (tree != NULL) + *tree = NULL; + + /* Create WBXML Parser */ + if((wbxml_parser = wbxml_parser_create()) == NULL) { + WBXML_ERROR((WBXML_PARSER, "Can't create WBXML Parser")); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Init context */ + wbxml_tree_clb_ctx.error = WBXML_OK; + wbxml_tree_clb_ctx.current = NULL; + if ((wbxml_tree_clb_ctx.tree = wbxml_tree_create(WBXML_LANG_UNKNOWN, WBXML_CHARSET_UNKNOWN)) == NULL) { + wbxml_parser_destroy(wbxml_parser); + WBXML_ERROR((WBXML_PARSER, "Can't create WBXML Tree")); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Set Handlers Callbacks */ + wbxml_parser_set_user_data(wbxml_parser, &wbxml_tree_clb_ctx); + wbxml_parser_set_content_handler(wbxml_parser, &wbxml_tree_content_handler); + + /* Give the user the possibility to force Document Language */ + if (lang != WBXML_LANG_UNKNOWN) + wbxml_parser_set_language(wbxml_parser, lang); + + /* Give the user the possibility to force the document character set */ + if (charset != WBXML_CHARSET_UNKNOWN) + wbxml_parser_set_meta_charset(wbxml_parser, charset); + + /* Parse the WBXML document to WBXML Tree */ + ret = wbxml_parser_parse(wbxml_parser, wbxml, wbxml_len); + if ((ret != WBXML_OK) || (wbxml_tree_clb_ctx.error != WBXML_OK)) + { + error_index = wbxml_parser_get_current_byte_index(wbxml_parser); + WBXML_ERROR((WBXML_PARSER, "WBXML Parser failed at %ld - token: %x (%s)", + error_index, + wbxml[error_index], + ret != WBXML_OK ? wbxml_errors_string(ret) : wbxml_errors_string(wbxml_tree_clb_ctx.error))); + + wbxml_tree_destroy(wbxml_tree_clb_ctx.tree); + } + else { + *tree = wbxml_tree_clb_ctx.tree; + } + + /* Clean-up */ + wbxml_parser_destroy(wbxml_parser); + + if (ret != WBXML_OK) + return ret; + else + return wbxml_tree_clb_ctx.error; +} + + +WBXML_DECLARE(WBXMLError) wbxml_tree_to_wbxml(WBXMLTree *tree, + WB_UTINY **wbxml, + WB_ULONG *wbxml_len, + WBXMLGenWBXMLParams *params) +{ + WBXMLEncoder *wbxml_encoder = NULL; + WBXMLError ret = WBXML_OK; + + /* Encode WBXML Tree to WBXML Document */ + if ((wbxml_encoder = wbxml_encoder_create()) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Set the WBXML Tree to encode */ + wbxml_encoder_set_tree(wbxml_encoder, tree); + + /* Set encoder parameters */ + if (params == NULL) { + /* Default Parameters */ + + /* Ignores "Empty Text" Nodes */ + wbxml_encoder_set_ignore_empty_text(wbxml_encoder, TRUE); + + /* Remove leading and trailing whitespaces in "Text Nodes" */ + wbxml_encoder_set_remove_text_blanks(wbxml_encoder, TRUE); + + /* Use String Table */ + wbxml_encoder_set_use_strtbl(wbxml_encoder, TRUE); + + /* Don't produce an anonymous document by default */ + wbxml_encoder_set_produce_anonymous(wbxml_encoder, FALSE); + } + else { + /* WBXML Version */ + wbxml_encoder_set_wbxml_version(wbxml_encoder, params->wbxml_version); + + /* Keep Ignorable Whitespaces ? */ + if (!params->keep_ignorable_ws) { + /* Ignores "Empty Text" Nodes */ + wbxml_encoder_set_ignore_empty_text(wbxml_encoder, TRUE); + + /* Remove leading and trailing whitespaces in "Text Nodes" */ + wbxml_encoder_set_remove_text_blanks(wbxml_encoder, TRUE); + } + + /* String Table */ + wbxml_encoder_set_use_strtbl(wbxml_encoder, params->use_strtbl); + + /* Produce an anonymous document? */ + wbxml_encoder_set_produce_anonymous(wbxml_encoder, + params->produce_anonymous); + + /** @todo Add parameter to call : wbxml_encoder_set_output_charset() */ + } + + /* Encode WBXML */ + ret = wbxml_encoder_encode_to_wbxml(wbxml_encoder, wbxml, wbxml_len); + + /* Clean-up */ + wbxml_encoder_destroy(wbxml_encoder); + + return ret; +} + + +WBXML_DECLARE(WBXMLError) wbxml_tree_from_xml(WB_UTINY *xml, WB_ULONG xml_len, WBXMLTree **tree) +{ +#if defined( HAVE_EXPAT ) + + const XML_Feature *feature_list = NULL; + XML_Parser xml_parser = NULL; + WBXMLError ret = WBXML_OK; + WB_BOOL expat_utf16 = FALSE; + WBXMLTreeClbCtx wbxml_tree_clb_ctx; + + /* First Check if Expat is outputing UTF-16 strings */ + feature_list = (const XML_Feature *)XML_GetFeatureList(); + + if ((feature_list != NULL) && (feature_list[0].value != sizeof(WB_TINY))) { +#if !defined( HAVE_ICONV ) + /* Ouch, can't convert from UTF-16 to UTF-8 */ + return WBXML_ERROR_XMLPARSER_OUTPUT_UTF16; +#else + /* Expat returns UTF-16 encoded strings in its callbacks */ + expat_utf16 = TRUE; +#endif /* !HAVE_ICONV */ + } + + if (tree != NULL) + *tree = NULL; + + /* Create Expat XML Parser */ + if ((xml_parser = XML_ParserCreateNS(NULL, WBXML_NAMESPACE_SEPARATOR)) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Init context */ + wbxml_tree_clb_ctx.current = NULL; + wbxml_tree_clb_ctx.error = WBXML_OK; + wbxml_tree_clb_ctx.skip_lvl = 0; + wbxml_tree_clb_ctx.skip_start = 0; + wbxml_tree_clb_ctx.xml_parser = xml_parser; + wbxml_tree_clb_ctx.input_buff = xml; + wbxml_tree_clb_ctx.expat_utf16 = expat_utf16; + + /* Create WBXML Tree */ + if ((wbxml_tree_clb_ctx.tree = wbxml_tree_create(WBXML_LANG_UNKNOWN, WBXML_CHARSET_UNKNOWN)) == NULL) { + XML_ParserFree(xml_parser); + WBXML_ERROR((WBXML_PARSER, "Can't create WBXML Tree")); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Set Handlers Callbacks */ + XML_SetXmlDeclHandler(xml_parser, wbxml_tree_clb_xml_decl); + XML_SetStartDoctypeDeclHandler(xml_parser, wbxml_tree_clb_xml_doctype_decl); + XML_SetElementHandler(xml_parser, wbxml_tree_clb_xml_start_element, wbxml_tree_clb_xml_end_element); + XML_SetCdataSectionHandler(xml_parser, wbxml_tree_clb_xml_start_cdata, wbxml_tree_clb_xml_end_cdata); + XML_SetProcessingInstructionHandler(xml_parser , wbxml_tree_clb_xml_pi); + XML_SetCharacterDataHandler(xml_parser, wbxml_tree_clb_xml_characters); + XML_SetUserData(xml_parser, (void*)&wbxml_tree_clb_ctx); + + /* Parse the XML Document to WBXML Tree */ + if (XML_Parse(xml_parser, (WB_TINY*) xml, xml_len, TRUE) == 0) + { + WBXML_ERROR((WBXML_CONV, "xml2wbxml conversion failed - expat error %i\n" + "\tdescription: %s\n" + "\tline: %i\n" + "\tcolumn: %i\n" + "\tbyte index: %i\n" + "\ttotal bytes: %i\n%s", + XML_GetErrorCode(xml_parser), + XML_ErrorString(XML_GetErrorCode(xml_parser)), + XML_GetCurrentLineNumber(xml_parser), + XML_GetCurrentColumnNumber(xml_parser), + XML_GetCurrentByteIndex(xml_parser), + XML_GetCurrentByteCount(xml_parser), xml)); + + wbxml_tree_destroy(wbxml_tree_clb_ctx.tree); + + ret = WBXML_ERROR_XML_PARSING_FAILED; + } + else { + if ((ret = wbxml_tree_clb_ctx.error) != WBXML_OK) + { + WBXML_ERROR((WBXML_CONV, "xml2wbxml conversion failed - context error %i", ret)); + wbxml_tree_destroy(wbxml_tree_clb_ctx.tree); + } + else + *tree = wbxml_tree_clb_ctx.tree; + } + + /* Clean-up */ + XML_ParserFree(xml_parser); + + return ret; + +#else /* HAVE_EXPAT */ + +#if defined( HAVE_LIBXML ) + + /** @todo Use LibXML2 SAX interface ! */ + return WBXML_ERROR_NO_XMLPARSER; + +#else /* HAVE_LIBXML */ + + /** @note You can add here another XML Parser support */ + return WBXML_ERROR_NO_XMLPARSER; + +#endif /* HAVE_LIBXML */ + +#endif /* HAVE_EXPAT */ +} + + +WBXML_DECLARE(WBXMLError) wbxml_tree_to_xml(WBXMLTree *tree, + WB_UTINY **xml, + WB_ULONG *xml_len, + WBXMLGenXMLParams *params) +{ + WBXMLEncoder *wbxml_encoder = NULL; + WBXMLError ret = WBXML_OK; + + /* Create WBXML Encoder */ + if ((wbxml_encoder = wbxml_encoder_create()) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Set the WBXML Tree to encode */ + wbxml_encoder_set_tree(wbxml_encoder, tree); + + /* Set encoder parameters */ + if (params == NULL) { + /* Default Values */ + + /* Set XML Generation Type */ + wbxml_encoder_set_xml_gen_type(wbxml_encoder, WBXML_GEN_XML_INDENT); + + /* Set Indent */ + wbxml_encoder_set_indent(wbxml_encoder, 0); + + /* Skip Ignorable Whitespaces */ + wbxml_encoder_set_ignore_empty_text(wbxml_encoder, TRUE); + wbxml_encoder_set_remove_text_blanks(wbxml_encoder, TRUE); + } + else { + /* Set XML Generation Type */ + wbxml_encoder_set_xml_gen_type(wbxml_encoder, params->gen_type); + + /* Set Indent */ + if (params->gen_type == WBXML_GEN_XML_INDENT) + wbxml_encoder_set_indent(wbxml_encoder, params->indent); + + /* Ignorable Whitespaces */ + if (params->keep_ignorable_ws) { + wbxml_encoder_set_ignore_empty_text(wbxml_encoder, FALSE); + wbxml_encoder_set_remove_text_blanks(wbxml_encoder, FALSE); + } + else { + wbxml_encoder_set_ignore_empty_text(wbxml_encoder, TRUE); + wbxml_encoder_set_remove_text_blanks(wbxml_encoder, TRUE); + } + + /** @todo Add parameter to call : wbxml_encoder_set_output_charset() */ + } + + /* Encode WBXML Tree to XML */ + ret = wbxml_encoder_encode_tree_to_xml(wbxml_encoder, xml, xml_len); + + /* Clean-up */ + wbxml_encoder_destroy(wbxml_encoder); + + return ret; +} + + +#if defined( HAVE_LIBXML ) + +WBXML_DECLARE(WBXMLError) wbxml_tree_from_libxml_doc(xmlDocPtr libxml_doc, + WBXMLTree **tree) +{ + /** @todo wbxml_tree_from_libxml_doc() */ + return WBXML_ERROR_NOT_IMPLEMENTED; +} + + +WBXML_DECLARE(WBXMLError) wbxml_tree_to_libxml_doc(WBXMLTree *tree, + xmlDocPtr *libxml_doc) +{ + /** @todo wbxml_tree_to_libxml_doc() */ + return WBXML_ERROR_NOT_IMPLEMENTED; +} + +#endif /* HAVE_LIBXML */ + + +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create(WBXMLTreeNodeType type) +{ + WBXMLTreeNode *result = NULL; + + if ((result = (WBXMLTreeNode *) wbxml_malloc(sizeof(WBXMLTreeNode))) == NULL) + return NULL; + + result->type = type; + result->name = NULL; + result->attrs = NULL; + result->content = NULL; + result->tree = NULL; + + result->parent = NULL; + result->children = NULL; + result->next = NULL; + result->prev = NULL; + + return result; +} + + +WBXML_DECLARE(void) wbxml_tree_node_destroy(WBXMLTreeNode *node) +{ + if (node == NULL) + return; + + wbxml_tag_destroy(node->name); + wbxml_list_destroy(node->attrs, wbxml_attribute_destroy_item); + wbxml_buffer_destroy(node->content); + wbxml_tree_destroy(node->tree); + + wbxml_free(node); +} + + +WBXML_DECLARE(void) wbxml_tree_node_destroy_item(void *node) +{ + wbxml_tree_node_destroy((WBXMLTreeNode *)node); +} + + +WBXML_DECLARE(void) wbxml_tree_node_destroy_all(WBXMLTreeNode *node) +{ + WBXMLTreeNode *parent_node = NULL; + WBXMLTreeNode *current_node = NULL; + WBXMLTreeNode *previous_node = NULL; + WBXMLTreeNode *tmp_node = NULL; + WB_BOOL end_of_walk = FALSE; + + if (node == NULL) + return; + + /* Let's go through the sub-tree (iteratively) to free all the nodes */ + current_node = node; + parent_node = node->parent; + + while (!end_of_walk) + { + if (current_node == NULL) { + /* Leaf reached */ + if (previous_node == NULL) { + end_of_walk = TRUE; + break; + } + else { + if (previous_node->parent == parent_node) { + /* End of parsing, we have parsed the last child of node */ + end_of_walk = TRUE; + break; + } + else { + /* Let's parse next child of parent node */ + current_node = previous_node->next; + tmp_node = previous_node->parent; + + /* Destroy this node (leaf) */ + wbxml_tree_node_destroy(previous_node); + + previous_node = tmp_node; + } + } + } + else { + /* Go deeper in sub-tree */ + previous_node = current_node; + current_node = current_node->children; + } + } + + wbxml_tree_node_destroy(node); +} + + +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_xml_elt(const WBXMLLangEntry *lang_table, + const WB_UTINY *name) +{ + const WBXMLTagEntry *tag_entry = NULL; + WBXMLTreeNode *node = NULL; + WBXMLTag *tag = NULL; + + /* Search for XML Tag Name in Table */ + if ((tag_entry = wbxml_tables_get_tag_from_xml(lang_table, -1, name)) != NULL) { + /* Found : token tag */ + tag = wbxml_tag_create_token(tag_entry); + } + else { + /* Not found : literal tag */ + tag = wbxml_tag_create_literal((WB_UTINY *)name); + } + + if (tag == NULL) + return NULL; + + /* Create a new Node */ + if ((node = wbxml_tree_node_create(WBXML_TREE_ELEMENT_NODE)) == NULL) { + wbxml_tag_destroy(tag); + return NULL; + } + + /* Set Node Tag */ + node->name = tag; + + return node; +} + + +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_xml_elt_with_text(const WBXMLLangEntry *lang_table, + const WB_UTINY *name, + const WB_UTINY *text, + WB_ULONG len) +{ + WBXMLTreeNode *node = NULL; + WBXMLTreeNode *text_node = NULL; + + /* Create element node */ + if ((node = wbxml_tree_node_create_xml_elt(lang_table, name)) == NULL) + return NULL; + + /* Create text node */ + if ((text_node = wbxml_tree_node_create_text(text, len)) == NULL) { + wbxml_tree_node_destroy(node); + return NULL; + } + + /* Add text node to element node */ + if (!wbxml_tree_node_add_child(node, text_node)) { + wbxml_tree_node_destroy(node); + wbxml_tree_node_destroy(text_node); + return NULL; + } + + return node; +} + + +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_text(const WB_UTINY *text, + WB_ULONG len) +{ + WBXMLTreeNode *node = NULL; + + /* Create a new Node */ + if ((node = wbxml_tree_node_create(WBXML_TREE_TEXT_NODE)) == NULL) { + return NULL; + } + + /* Set Content */ + if ((node->content = wbxml_buffer_create(text, len, len)) == NULL) { + wbxml_tree_node_destroy(node); + return NULL; + } + + return node; +} + + +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_cdata(const WB_UTINY *text, + WB_ULONG len) +{ + WBXMLTreeNode *node = NULL; + WBXMLTreeNode *text_node = NULL; + + /* Create a new node */ + if ((node = wbxml_tree_node_create(WBXML_TREE_CDATA_NODE)) == NULL) { + return NULL; + } + + /* Create a text node */ + if ((text_node = wbxml_tree_node_create_text(text, len)) == NULL) { + wbxml_tree_node_destroy(node); + return NULL; + } + + /* Add text node to cdata */ + if (!wbxml_tree_node_add_child(node, text_node)) { + wbxml_tree_node_destroy_all(node); + node = NULL; + } + + return node; +} + + +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_tree(WBXMLTreeNode *root, + WBXMLLanguage lang, + WBXMLCharsetMIBEnum orig_charset) +{ + WBXMLTreeNode* result = NULL; + WBXMLTree* tree = NULL; + + if ((root == NULL) || (lang == WBXML_LANG_UNKNOWN)) + return NULL; + + /* Create Tree */ + if ((tree = wbxml_tree_create(lang, orig_charset)) == NULL) + return NULL; + + /* Fill Tree */ + tree->root = root; + + /* Create Tree Node */ + if ((result = wbxml_tree_node_create(WBXML_TREE_TREE_NODE)) == NULL) { + wbxml_tree_destroy(tree); + return NULL; + } + + /* Fill Tree Node */ + result->tree = tree; + + return result; +} + + +WBXML_DECLARE(WB_BOOL) wbxml_tree_node_add_child(WBXMLTreeNode *parent, + WBXMLTreeNode *node) +{ + WBXMLTreeNode *tmp = NULL; + + if ((parent == NULL) || (node == NULL)) + return FALSE; + + /* Set parent to new node */ + node->parent = parent; + + /* Search for previous sibbling element */ + if (parent->children != NULL) { + /* Add this Node to end of Sibbling Node list of Parent */ + tmp = parent->children; + + while (tmp->next != NULL) + tmp = tmp->next; + + node->prev = tmp; + tmp->next = node; + } + else { + /* No previous sibbling element */ + parent->children = node; + } + + return TRUE; +} + + +WBXML_DECLARE(WBXMLError) wbxml_tree_node_add_attr(WBXMLTreeNode *node, + WBXMLAttribute *attr) +{ + WBXMLAttribute *new_attr = NULL; + + if ((node == NULL) || (attr == NULL)) { + return WBXML_ERROR_BAD_PARAMETER; + } + + /* Create list if needed */ + if (node->attrs == NULL) { + if ((node->attrs = wbxml_list_create()) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + + /* Duplicate Attribute */ + if ((new_attr = wbxml_attribute_duplicate(attr)) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Add attribute to list */ + if (!wbxml_list_append(node->attrs, new_attr)) { + wbxml_attribute_destroy(attr); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + return WBXML_OK; +} + + +WBXML_DECLARE(WBXMLError) wbxml_tree_node_add_attrs(WBXMLTreeNode *node, + WBXMLAttribute **attrs) +{ + WB_ULONG i = 0; + + if ((node == NULL) || (attrs == NULL)) { + return WBXML_ERROR_BAD_PARAMETER; + } + + while (attrs[i] != NULL) { + /* Add attribute */ + if (wbxml_tree_node_add_attr(node, attrs[i]) != WBXML_OK) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + i++; + } + + return WBXML_OK; +} + + +WBXML_DECLARE(WBXMLError) wbxml_tree_node_add_xml_attr(const WBXMLLangEntry *lang_table, + WBXMLTreeNode *node, + const WB_UTINY *name, + const WB_UTINY *value) +{ + WBXMLAttribute *attr = NULL; + const WBXMLAttrEntry *attr_entry = NULL; + + /* Create list if needed */ + if (node->attrs == NULL) { + if ((node->attrs = wbxml_list_create()) == NULL) { + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + } + + /* Create Attribute */ + if ((attr = wbxml_attribute_create()) == NULL) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + /* Set Attribute Name */ + if ((attr_entry = wbxml_tables_get_attr_from_xml(lang_table, (WB_UTINY *)name, (WB_UTINY *)value, NULL)) != NULL) + attr->name = wbxml_attribute_name_create_token(attr_entry); + else + attr->name = wbxml_attribute_name_create_literal((WB_UTINY *)name); + + if (attr->name == NULL) { + wbxml_attribute_destroy(attr); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Set Attribute Value */ + attr->value = wbxml_buffer_create_real(value, WBXML_STRLEN(value), WBXML_STRLEN(value)); + if (attr->value == NULL) { + wbxml_attribute_destroy(attr); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + /* Add attribute to list */ + if (!wbxml_list_append(node->attrs, attr)) { + wbxml_attribute_destroy(attr); + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + + return WBXML_OK; +} + + +WBXML_DECLARE(WBXMLError) wbxml_tree_node_add_xml_attrs(const WBXMLLangEntry *lang_table, + WBXMLTreeNode *node, + const WB_UTINY **attrs) +{ + const WB_UTINY **p = attrs; + + if ((lang_table == NULL) || (node == NULL) || (attrs == NULL)) + return WBXML_ERROR_BAD_PARAMETER; + + while (p && *p) { + /* Add attribute */ + if (wbxml_tree_node_add_xml_attr(lang_table, node, *p, *(p+1)) != WBXML_OK) + return WBXML_ERROR_NOT_ENOUGH_MEMORY; + + p += 2; + } + + return WBXML_OK; +} + + +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_elt_get_from_name(WBXMLTreeNode *node, const char *name, WB_BOOL recurs) +{ + WBXMLTreeNode *current_node = NULL; + WBXMLTreeNode *recurs_node = NULL; + + if ((node == NULL) || (name == NULL)) + return NULL; + + /* Let's go through the tree */ + current_node = node; + + while (current_node != NULL) + { + /* Is this a normal node? */ + if (current_node->type == WBXML_TREE_ELEMENT_NODE) + { + /* Is this the Node we searched ? */ + if (WBXML_STRCMP(wbxml_tag_get_xml_name(current_node->name), name) == 0) + { + return current_node; + } + + /* Sould we start a recursive search? */ + if (recurs && current_node->children) + { + recurs_node = wbxml_tree_node_elt_get_from_name(current_node->children, name, TRUE); + /* Is this the Node we searched ? */ + if (recurs_node) + { + return recurs_node; + } + } + } + + /* Go to next Sibbling Node */ + current_node = current_node->next; + } + + /* A node with the specified name could not be found. */ + return NULL; +} + + +#if defined ( WBXML_SUPPORT_SYNCML ) + +WBXML_DECLARE(WBXMLSyncMLDataType) wbxml_tree_node_get_syncml_data_type(WBXMLTreeNode *node) +{ + WBXMLTreeNode *tmp_node = NULL; + + if (node == NULL) + return WBXML_SYNCML_DATA_TYPE_NORMAL; + + /* If we are in a CDATA node then we must look into the parent node. */ + if (node->type == WBXML_TREE_CDATA_NODE) + node = node->parent; + + /* Are we in a ? */ + if ((node->type == WBXML_TREE_ELEMENT_NODE) && + (node->name != NULL) && + (WBXML_STRCMP(wbxml_tag_get_xml_name(node->name), "Data") == 0)) + { + /* Go to Parent element (or Parent of Parent) and search for then */ + if (((node->parent != NULL) && + (node->parent->children != NULL) && + ((tmp_node = wbxml_tree_node_elt_get_from_name(node->parent->children, "Meta", FALSE)) != NULL) && + ((tmp_node = wbxml_tree_node_elt_get_from_name(tmp_node->children, "Type", FALSE)) != NULL)) || + (((node->parent != NULL) && + (node->parent->parent != NULL) && + (node->parent->parent->children != NULL) && + ((tmp_node = wbxml_tree_node_elt_get_from_name(node->parent->parent->children, "Meta", FALSE)) != NULL)) && + ((tmp_node = wbxml_tree_node_elt_get_from_name(tmp_node->children, "Type", FALSE)) != NULL))) + { + /* Check value */ + if ((tmp_node->children != NULL) && (tmp_node->children->type == WBXML_TREE_TEXT_NODE)) { + /* This function is used by wbxml and xml callbacks. + * So content types must be handled for both situations. + */ + + /* application/vnd.syncml-devinf+wbxml */ + if (wbxml_buffer_compare_cstr(tmp_node->children->content, "application/vnd.syncml-devinf+wbxml") == 0) { + return WBXML_SYNCML_DATA_TYPE_WBXML; + } + + /* application/vnd.syncml-devinf+xml */ + if (wbxml_buffer_compare_cstr(tmp_node->children->content, "application/vnd.syncml-devinf+xml") == 0) { + return WBXML_SYNCML_DATA_TYPE_NORMAL; + } + + /* application/vnd.syncml.dmtnds+wbxml */ + if (wbxml_buffer_compare_cstr(tmp_node->children->content, "application/vnd.syncml.dmtnds+wbxml") == 0) { + return WBXML_SYNCML_DATA_TYPE_WBXML; + } + + /* application/vnd.syncml.dmtnds+xml */ + if (wbxml_buffer_compare_cstr(tmp_node->children->content, "application/vnd.syncml.dmtnds+xml") == 0) { + return WBXML_SYNCML_DATA_TYPE_NORMAL; + } + + /* text/clear */ + if (wbxml_buffer_compare_cstr(tmp_node->children->content, "text/clear") == 0) { + return WBXML_SYNCML_DATA_TYPE_CLEAR; + } + + /* text/directory;profile=vCard */ + if (wbxml_buffer_compare_cstr(tmp_node->children->content, "text/directory;profile=vCard") == 0) { + return WBXML_SYNCML_DATA_TYPE_DIRECTORY_VCARD; + } + + /* text/x-vcard */ + if (wbxml_buffer_compare_cstr(tmp_node->children->content, "text/x-vcard") == 0) { + return WBXML_SYNCML_DATA_TYPE_VCARD; + } + + /* text/x-vcalendar */ + if (wbxml_buffer_compare_cstr(tmp_node->children->content, "text/x-vcalendar") == 0) { + return WBXML_SYNCML_DATA_TYPE_VCALENDAR; + } + } + } + + /** + * Hack: we assume that any inside a or Item is a vObject (vCard / vCal / ...). + * + * This is because when parsing a content we really need to put a CDATA, event if we don't really + * know the content-type. For example when receiving the end of a splitted vObject with Samsung D600, we receive this: + * + * + * 162 + * + * + * ./690 + * + * EF;CELL:0661809055 + * TEL;HOME:0299783886 + * X-IRMC-LUID:690 + * END:VCARD + * + * + * + * There is no info to find the content-type of the . + */ + if ( (node->parent != NULL) && + (node->parent->parent != NULL) && + (node->parent->parent->name != NULL) && + ((WBXML_STRCMP(wbxml_tag_get_xml_name(node->parent->parent->name), "Add") == 0) || + (WBXML_STRCMP(wbxml_tag_get_xml_name(node->parent->parent->name), "Replace") == 0)) ) + { + return WBXML_SYNCML_DATA_TYPE_VOBJECT; + } + } + + return WBXML_SYNCML_DATA_TYPE_NORMAL; +} + +#endif /* WBXML_SUPPORT_SYNCML */ + + +WBXML_DECLARE(WB_BOOL) wbxml_tree_node_have_child_elt(WBXMLTreeNode *node) +{ + WBXMLTreeNode *current = NULL; + + if (node != NULL) { + /* Get first child */ + current = node->children; + + while (current != NULL) { + if (current->type == WBXML_TREE_ELEMENT_NODE) { + /* Element Node found ! */ + return TRUE; + } + + /* Check next child */ + current = current->next; + } + } + + return FALSE; +} + + +WBXML_DECLARE(WBXMLList*) wbxml_tree_node_get_all_children(WBXMLTreeNode *node) +{ + WBXMLList* result = NULL; + + if ( node == NULL ) + return NULL; + + node = node->children; + + while ( node != NULL ) { + /* Create result list if not already done */ + if ( result == NULL ) + result = wbxml_list_create(); + + /* Append node to result */ + wbxml_list_append(result, node); + + /* Go to next node */ + node = node->next; + } + + return result; +} + + +WBXML_DECLARE(WBXMLTree *) wbxml_tree_create(WBXMLLanguage lang, + WBXMLCharsetMIBEnum orig_charset) +{ + WBXMLTree *result = NULL; + + if ((result = (WBXMLTree *) wbxml_malloc(sizeof(WBXMLTree))) == NULL) + return NULL; + + result->lang = wbxml_tables_get_table(lang); + result->root = NULL; + result->orig_charset = orig_charset; + result->cur_code_page = 0; + + return result; +} + + +WBXML_DECLARE(void) wbxml_tree_destroy(WBXMLTree *tree) +{ + if (tree != NULL) { + /* Destroy root node and all its children */ + wbxml_tree_node_destroy_all(tree->root); + + /* Free tree */ + wbxml_free(tree); + } +} + + +/** @todo Rewrite this function (use wbxml_tree_node_* functions) */ +WBXML_DECLARE(WB_BOOL) wbxml_tree_add_node(WBXMLTree *tree, WBXMLTreeNode *parent, WBXMLTreeNode *node) +{ + WBXMLTreeNode *tmp = NULL; + + if ((tree == NULL) || (node == NULL)) + return FALSE; + + /* Set parent to new node */ + node->parent = parent; + + /* Check if this is the Root Element */ + if (parent != NULL) { + /* This is not the Root Element... search for previous sibbling element */ + if (parent->children != NULL) { + /* Add this Node to end of Sibbling Node list of Parent */ + tmp = parent->children; + + /* !!! WARNING !!! + * EXPAT splits <html> into three separate text nodes. + * Therefore it is necessary to scan for splitted text nodes and + * join them to get consistent text nodes. + */ + + /* If the handled node is a text node and the last node is a text node + * then the last node must be replace. + * Otherwise the node will be appended. + */ + while (tmp->next != NULL) + tmp = tmp->next; + + if (node->type == WBXML_TREE_TEXT_NODE && + tmp->type == WBXML_TREE_TEXT_NODE) { + + /* join the two text nodes and replace the present text node */ + if (!wbxml_buffer_append(tmp->content, node->content)) + return FALSE; + + if (tmp->prev == NULL) { + /* tmp is first child */ + parent->children = node; + } else { + /* tmp is not first child */ + tmp->prev->next = node; + node->prev = tmp->prev; + } + + wbxml_buffer_destroy(node->content); + node->content = tmp->content; + tmp->content = NULL; + wbxml_tree_node_destroy(tmp); + } else { + /* normal situation => append node */ + node->prev = tmp; + tmp->next = node; + } + } + else { + /* No previous sibbling element */ + parent->children = node; + } + } + else { + /* We do NOT allow replacement of an existing Tree Node */ + if (tree->root != NULL) + return FALSE; + + /* This is the Root Element */ + tree->root = node; + } + + return TRUE; +} + + +/** @todo Rewrite this function (use wbxml_tree_node_* functions) */ +WBXML_DECLARE(WBXMLError) wbxml_tree_extract_node(WBXMLTree *tree, + WBXMLTreeNode *node) +{ + if ((tree == NULL) || (node == NULL)) + return WBXML_ERROR_BAD_PARAMETER; + + /* Parent link */ + if (node->parent != NULL) { + if (node->parent->children == node) { + /* Update parent children */ + node->parent->children = node->next; + } + + /* No more parent */ + node->parent = NULL; + } + else { + /* Root removed ! */ + tree->root = node->next; + } + + /* Link next node to previous node */ + if (node->next != NULL) + node->next->prev = node->prev; + + /* Link previous node to next node */ + if (node->prev != NULL) + node->prev->next = node->next; + + /* Cleanup pointers */ + node->next = node->prev = NULL; + + return WBXML_OK; +} + + +/** @todo Rewrite this function (use wbxml_tree_node_* functions) */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_elt(WBXMLTree *tree, + WBXMLTreeNode *parent, + WBXMLTag *tag) +{ + WBXMLTreeNode *node = NULL; + + /* Create a new Node */ + if ((node = wbxml_tree_node_create(WBXML_TREE_ELEMENT_NODE)) == NULL) { + return NULL; + } + + /* Set Element */ + if ((node->name = wbxml_tag_duplicate(tag)) == NULL) { + wbxml_tree_node_destroy(node); + return NULL; + } + + /* Add this Node to Tree */ + if (!wbxml_tree_add_node(tree, parent, node)) { + wbxml_tree_node_destroy(node); + return NULL; + } + + return node; +} + + +/** @todo Rewrite this function (use wbxml_tree_node_* functions) */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_elt_with_attrs(WBXMLTree *tree, + WBXMLTreeNode *parent, + WBXMLTag *tag, + WBXMLAttribute **attrs) +{ + WBXMLTreeNode *node = NULL; + + /* Add element */ + if ((node = wbxml_tree_add_elt(tree, parent, tag)) == NULL) { + return NULL; + } + + /* Add attributes to element */ + if ((attrs != NULL) && (*attrs != NULL)) { + if (wbxml_tree_node_add_attrs(node, attrs) != WBXML_OK) { + /* Remove node from Tree */ + wbxml_tree_extract_node(tree, node); + wbxml_tree_node_destroy(node); + return NULL; + } + } + + return node; +} + + +/** @todo Rewrite this function (use wbxml_tree_node_* functions) */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_xml_elt(WBXMLTree *tree, + WBXMLTreeNode *parent, + WB_UTINY *name) +{ + const WBXMLTagEntry *tag_entry = NULL; + WBXMLTreeNode *node = NULL; + WBXMLTag *tag = NULL; + WB_UTINY *sep = NULL; + const WB_UTINY *namespace_name = NULL; + WB_UTINY *element_name = NULL; + + /* Separate the namespace from the element name */ + sep = (WB_UTINY *)strrchr((const WB_TINY *) name, WBXML_NAMESPACE_SEPARATOR); + if (sep != NULL) { + /* Temporarily split the string by changing the separater to a null-terminator */ + *sep = '\0'; + + namespace_name = name; + element_name = sep+1; + } + else { + /* No namespace, so just set it to an empty string (specifically, the null-terminator at the end of the elemet name */ + namespace_name = name + strlen((const WB_TINY *) name); + element_name = name; + } + + WBXML_DEBUG((WBXML_CONV, "Parsed element name: Namespace='%s', Element='%s'", namespace_name, element_name)); + + /* Update the current code page to match the one specified by the namespace */ + tree->cur_code_page = wbxml_tables_get_code_page(tree->lang->nsTable, (const WB_TINY *) namespace_name); + + /* Search for XML Tag Name in Table */ + if ((tag_entry = wbxml_tables_get_tag_from_xml(tree->lang, tree->cur_code_page, element_name)) != NULL) { + tree->cur_code_page = tag_entry->wbxmlCodePage; + + /* Found : token tag */ + tag = wbxml_tag_create_token(tag_entry); + } + else { + /* Not found : literal tag */ + tag = wbxml_tag_create_literal(element_name); + } + + if (sep != NULL) { + /* We are done with the element and namespace names, so put the separator character back */ + *sep = WBXML_NAMESPACE_SEPARATOR; + } + + if (tag == NULL) + return NULL; + + /* Create a new Node */ + if ((node = wbxml_tree_node_create(WBXML_TREE_ELEMENT_NODE)) == NULL) { + wbxml_tag_destroy(tag); + return NULL; + } + + /* Set Node Tag */ + node->name = tag; + + /* Add this Node to Tree */ + if (!wbxml_tree_add_node(tree, parent, node)) { + wbxml_tree_node_destroy(node); + return NULL; + } + + return node; +} + + +/** @todo Rewrite this function (use wbxml_tree_node_* functions) */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_xml_elt_with_attrs(WBXMLTree *tree, + WBXMLTreeNode *parent, + WB_UTINY *name, + const WB_UTINY **attrs) +{ + WBXMLTreeNode *node = NULL; + + /* Add element */ + if ((node = wbxml_tree_add_xml_elt(tree, parent, name)) == NULL) { + return NULL; + } + + /* Add attributes to element */ + if ((attrs != NULL) && (*attrs != NULL)) { + if (wbxml_tree_node_add_xml_attrs(tree->lang, node, attrs) != WBXML_OK) { + /* Remove node from Tree */ + wbxml_tree_extract_node(tree, node); + wbxml_tree_node_destroy(node); + return NULL; + } + } + + return node; +} + + +/** @todo Rewrite this function (use wbxml_tree_node_* functions) */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_text(WBXMLTree *tree, + WBXMLTreeNode *parent, + const WB_UTINY *text, + WB_ULONG len) +{ + WBXMLTreeNode *node = NULL; + + /* Create a new Node */ + if ((node = wbxml_tree_node_create(WBXML_TREE_TEXT_NODE)) == NULL) { + return NULL; + } + + /* Set Content */ + if ((node->content = wbxml_buffer_create(text, len, len)) == NULL) { + wbxml_tree_node_destroy(node); + return NULL; + } + + /* Add this Node to Tree */ + if (!wbxml_tree_add_node(tree, parent, node)) { + wbxml_tree_node_destroy(node); + return NULL; + } + + return node; +} + + +/** @todo Rewrite this function (use wbxml_tree_node_* functions) */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_cdata(WBXMLTree *tree, + WBXMLTreeNode *parent) +{ + WBXMLTreeNode *node = NULL; + + /* Create a new Node */ + if ((node = wbxml_tree_node_create(WBXML_TREE_CDATA_NODE)) == NULL) { + return NULL; + } + + /* Add this Node to Tree */ + if (!wbxml_tree_add_node(tree, parent, node)) { + wbxml_tree_node_destroy(node); + return NULL; + } + + return node; +} + + +/** @todo wbxml_tree_add_cdata_with_text() */ + + +/** @todo Rewrite this function (use wbxml_tree_node_* functions) */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_tree(WBXMLTree *tree, + WBXMLTreeNode *parent, + WBXMLTree *new_tree) +{ + WBXMLTreeNode *node = NULL; + + /* Create a new Node */ + if ((node = wbxml_tree_node_create(WBXML_TREE_TREE_NODE)) == NULL) { + return NULL; + } + + /* Add this Node to Tree */ + if (!wbxml_tree_add_node(tree, parent, node)) { + wbxml_tree_node_destroy(node); + return NULL; + } + + /* Set Tree */ + node->tree = new_tree; + + return node; +} + + +/** @todo Rewrite this function (use wbxml_tree_node_* functions) */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_xml_elt_with_attrs_and_text(WBXMLTree *tree, + WBXMLTreeNode *parent, + WB_UTINY *name, + const WB_UTINY **attrs, + const WB_UTINY *text, + WB_ULONG len) +{ + WBXMLTreeNode *new_node = NULL; + + /* Add XML node */ + if ((new_node = wbxml_tree_add_xml_elt_with_attrs(tree, parent, name, attrs)) == NULL) + return NULL; + + /* Add text node */ + if ((text != NULL) && (len > 0)) { + if (wbxml_tree_add_text(tree, new_node, text, len) == NULL) { + wbxml_tree_node_destroy(new_node); + return NULL; + } + } + + return new_node; +} diff --git a/src/wbxml_tree.h b/src/wbxml_tree.h new file mode 100644 index 0000000..3c5a6ad --- /dev/null +++ b/src/wbxml_tree.h @@ -0,0 +1,563 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_tree.h + * @ingroup wbxml_tree + * + * @author Aymerick Jehanne + * @date 03/02/16 + * + * @brief WBXML Tree + */ + +#ifndef WBXML_TREE_H +#define WBXML_TREE_H + +#include "wbxml.h" +#include "wbxml_elt.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include + +/** @addtogroup wbxml_tree + * @{ + */ + + +/**************************************************** + * WBXML Tree Structures + */ + + +/** + * @brief WBXML Tree Node Type + */ +typedef enum WBXMLTreeNodeType_e +{ + WBXML_TREE_ELEMENT_NODE = 0, /**< Element Node */ + WBXML_TREE_TEXT_NODE, /**< Text Node */ + WBXML_TREE_CDATA_NODE, /**< CDATA Node */ + WBXML_TREE_PI_NODE, /**< PI Node */ + WBXML_TREE_TREE_NODE /**< WBXML Tree Node */ +} WBXMLTreeNodeType; + +/** + * @brief WBXML Tree Node structure + */ +typedef struct WBXMLTreeNode_s +{ + WBXMLTreeNodeType type; /**< Node Type */ + WBXMLTag *name; /**< Node Name (if type is 'WBXML_TREE_ELEMENT_NODE') */ + WBXMLList *attrs; /**< Node Attributes (if type is 'WBXML_TREE_ELEMENT_NODE') */ + WBXMLBuffer *content; /**< Node Content (if type is 'WBXML_TREE_TEXT_NODE') */ + struct WBXMLTree_s *tree; /**< Node Tree (if type is 'WBXML_TREE_TREE_NODE') */ + + struct WBXMLTreeNode_s *parent; /**< Parent Node */ + struct WBXMLTreeNode_s *children; /**< Children Node */ + struct WBXMLTreeNode_s *next; /**< Next sibling Node */ + struct WBXMLTreeNode_s *prev; /**< Previous sibling Node */ +} WBXMLTreeNode; + + +/** + * @brief WBXML Tree structure + * + * This structure is created when parsing a WBXML or XML document, thanks to + * the functions wbxml_tree_from_wbxml() and wbxml_tree_from_xml(). + * + * It represents the parsed document, and have this fields: + * - lang: the language table of the parsed document (in wbxml_tables.c) + * - root: the root element of the Tree representing the parsed document + * - orig_charset: the original charset encoding of the parsed document + * + * @note All the strings inside the WBXML Tree are encoded into UTF-8 + */ +typedef struct WBXMLTree_s +{ + const WBXMLLangEntry *lang; /**< Language Table */ + WBXMLTreeNode *root; /**< Root Element */ + WBXMLCharsetMIBEnum orig_charset; /**< Charset encoding of original document */ + WB_UTINY cur_code_page;/**< Last seen code page */ +} WBXMLTree; + + +/** + * WBXML Tree Clb Context Structure + * @note Used by WBXML Tree Callbacks ('wbxml_tree_clb_wbxml.h' and 'wbxml_tree_clb_xml.h') + */ +typedef struct WBXMLTreeClbCtx_s { + /* For XML and WBXML Clb */ + WBXMLTree *tree; /**< The WBXML Tree we are constructing */ + WBXMLTreeNode *current; /**< Current Tree Node */ + WBXMLError error; /**< Error while parsing Document */ + /* For XML Clb */ + WB_ULONG skip_lvl; /**< Used to skip a whole XML node (used for SyncML) */ + WB_LONG skip_start; /**< Starting Skipping position in XML Document (used for SyncML) */ + WB_UTINY *input_buff; /**< Pointer to Input Buffer */ +#if defined( HAVE_EXPAT ) + XML_Parser xml_parser; /**< Pointer to Expat XML Parser */ + WB_BOOL expat_utf16; /**< Is Expat compiled to output UTF-16 ? */ +#endif /* HAVE_EXPAT */ +} WBXMLTreeClbCtx; + + +#if defined ( WBXML_SUPPORT_SYNCML ) +/** + * SyncML Data Type (the type of data inside element) + */ +typedef enum WBXMLSyncMLDataType_e { + WBXML_SYNCML_DATA_TYPE_NORMAL = 0, /**< Not specific Data Type */ + WBXML_SYNCML_DATA_TYPE_WBXML, /**< application/vnd.syncml-devinf+wbxml (WBXML Document) */ + WBXML_SYNCML_DATA_TYPE_CLEAR, /**< text/clear */ + WBXML_SYNCML_DATA_TYPE_DIRECTORY_VCARD, /**< text/directory;profile=vCard */ + WBXML_SYNCML_DATA_TYPE_VCARD, /**< text/x-vcard */ + WBXML_SYNCML_DATA_TYPE_VCALENDAR, /**< text/x-vcalendar */ + WBXML_SYNCML_DATA_TYPE_VOBJECT /**< Hack: we assume that any inside a or Item is a vObjec (vCard / vCal / ...) */ +} WBXMLSyncMLDataType; +#endif /* WBXML_SUPPORT_SYNCML */ + + +/**************************************************** + * WBXML Tree Building Functions + */ + +/** + * @brief Parse a WBXML document, using internal callbacks (in wbxml_tree_clb_wbxml.c), and construct a WBXML Tree + * @param wbxml [in] The WBXML document to parse + * @param wbxml_len [in] The WBXML document length + * @param lang [in] Can be used to force parsing of a given Language (set it to WBXML_LANG_UNKNOWN if you don't want to force anything) + * @param tree [out] The resulting WBXML Tree + * @result Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_from_wbxml(WB_UTINY *wbxml, + WB_ULONG wbxml_len, + WBXMLLanguage lang, + WBXMLCharsetMIBEnum charset, + WBXMLTree **tree); + +/** + * @brief Convert a WBXML Tree to a WBXML document + * @param tree [in] The WBXML Tree to convert + * @param wbxml [out] The resulting WBXML document + * @param wbxml_len [out] The resulting WBXML document length + * @param params [in] Parameters (if NULL, default values are used) + * @result Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_to_wbxml(WBXMLTree *tree, + WB_UTINY **wbxml, + WB_ULONG *wbxml_len, + WBXMLGenWBXMLParams *params); + +/** + * @brief Parse an XML document, using internal callbacks (in wbxml_tree_clb_xml.c), and construct a WBXML Tree + * @param xml [in] The XML document to parse + * @param xml_len [in] Length of the XML document + * @param tree [out] The resulting WBXML Tree + * @result Return WBXML_OK if no error, an error code otherwise + * @note Needs 'HAVE_EXPAT' compile flag + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_from_xml(WB_UTINY *xml, + WB_ULONG xml_len, + WBXMLTree **tree); + +/** + * @brief Convert a WBXML Tree to an XML document + * @param tree [in] The WBXML Tree to convert + * @param xml [out] The resulting XML document + * @param xml_len [out] The resulting XML document length + * @param params [in] Parameters (if NULL, default values are used) + * @result Return WBXML_OK if no error, an error code otherwise + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_to_xml(WBXMLTree *tree, + WB_UTINY **xml, + WB_ULONG *xml_len, + WBXMLGenXMLParams *params); + +/** @todo Libxml support ! */ +#if defined( HAVE_LIBXML ) + +/** + * @brief Parse a LibXML document, and construct the corresponding WBXML Tree + * @param libxml_doc [in] The LibXML document to parse + * @param tree [out] The resulting WBXML Tree + * @result Return WBXML_OK if no error, an error code otherwise + * @note Needs 'HAVE_LIBXML' compile flag + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_from_libxml_doc(xmlDocPtr libxml_doc, + WBXMLTree **tree); + +/** + * @brief Parse a WBXML Tree, and construct the corresponding LibXML document + * @param tree [in] The WBXML Tree to parse + * @param libxml_doc [out] The resulting LibXML document + * @result Return WBXML_OK if no error, an error code otherwise + * @note Needs 'HAVE_LIBXML' compile flag + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_to_libxml_doc(WBXMLTree *tree, + xmlDocPtr *libxml_doc); + +#endif /* HAVE_LIBXML */ + + +/**************************************************** + * WBXML Tree Functions + */ + +/** + * @brief Create a Tree Node structure + * @param type Node type + * @return The newly created Tree Node, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create(WBXMLTreeNodeType type); + +/** + * @brief Destroy a Tree Node structure + * @param node The Tree Node structure to destroy + * @note The Node is freed, but not extracted from its WBXML Tree (use wbxml_tree_extract_node() before) + */ +WBXML_DECLARE(void) wbxml_tree_node_destroy(WBXMLTreeNode *node); + +/** + * @brief Destroy a Tree Node structure (used for wbxml_list_destroy()) + * @param node The Tree Node structure to destroy + */ +WBXML_DECLARE(void) wbxml_tree_node_destroy_item(void *node); + +/** + * @brief Destroy a Tree Node structure, and all its children + * @param node The Tree Node structure to destroy + * @note The Node (and its sub-tree) is freed, but not extracted from its WBXML Tree (use wbxml_tree_extract_node() before) + */ +WBXML_DECLARE(void) wbxml_tree_node_destroy_all(WBXMLTreeNode *node); + +/** + * @brief Create a Tree Node structure, given the XML node name + * @param lang_table Language table + * @param name XML node name + * @return The newly created Tree Node, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_xml_elt(const WBXMLLangEntry *lang_table, + const WB_UTINY *name); + +/** + * @brief Create a Tree Node structure, given the XML node name and text content + * @param lang_table Language table + * @param name XML node name + * @param text Text content + * @param len Text content length + * @return The newly created Tree Node, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_xml_elt_with_text(const WBXMLLangEntry *lang_table, + const WB_UTINY *name, + const WB_UTINY *text, + WB_ULONG len); + +/** + * @brief Create a Text Node structure + * @param text Text content + * @param len Text content length + * @return The newly created Tree Node, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_text(const WB_UTINY *text, + WB_ULONG len); + +/** + * @brief Create a CDATA Node structure + * @param text Text content + * @param len Text content length + * @return The newly created Tree Node, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_cdata(const WB_UTINY *text, + WB_ULONG len); + +/** + * @brief Create a Tree Node structure + * @param root Root node for this Tree + * @param lang Language table to use + * @param orig_charset Original charset + * @return The newly created Tree Node, or NULL if not enough memory + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create_tree(WBXMLTreeNode *root, + WBXMLLanguage lang, + WBXMLCharsetMIBEnum orig_charset); + +/** + * @brief Add a Child node + * @param parent Parent node + * @param node Child node to add + * @return TRUE if added or FALSE if error + */ +WBXML_DECLARE(WB_BOOL) wbxml_tree_node_add_child(WBXMLTreeNode *parent, + WBXMLTreeNode *node); + +/** + * @brief Extract a node + * @param node Node to extract + * @return TRUE if extracted or FALSE if error + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_node_extract(WBXMLTreeNode *node); + +/** + * @brief Add a WBXML Attribute to a Tree Node structure + * @param node The Tree Node to modify + * @param attr The WBXML Attribute to add + * @return WBXML_OK if no error, an error code otherwise + * @note This is only meanfull for an element node + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_node_add_attr(WBXMLTreeNode *node, + WBXMLAttribute *attr); + +/** + * @brief Add a WBXML Attributes list to a Tree Node structure + * @param node The Tree Node to modify + * @param attrs The WBXML Attributes to add + * @return WBXML_OK if no error, an error code otherwise + * @note This is only meanfull for an element node + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_node_add_attrs(WBXMLTreeNode *node, + WBXMLAttribute **attrs); + +/** + * @brief Add an XML Attribute to a Tree Node structure + * @param lang_table Language table + * @param node The Tree Node to modify + * @param name The XML Attribute name + * @param value The XML Attribute value + * @return WBXML_OK if no error, an error code otherwise + * @note This is only meanfull for an element node + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_node_add_xml_attr(const WBXMLLangEntry *lang_table, + WBXMLTreeNode *node, + const WB_UTINY *name, + const WB_UTINY *value); + +/** + * @brief Add an XML Attributes list to a Tree Node structure + * @param lang_table Language table + * @param node The Tree Node to modify + * @param attrs The XML Attributes to add + * @return WBXML_OK if no error, an error code otherwise + * @note This is only meanfull for an element node + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_node_add_xml_attrs(const WBXMLLangEntry *lang_table, + WBXMLTreeNode *node, + const WB_UTINY **attrs); + +/** + * @brief Get an Element Node, given the Element Name + * @param node The Tree Node where to start searching + * @param name The Element Name we are searching + * @param recurs If FALSE, only search into direct childs of 'node' + * @return The found Tree Node, or NULL if not found + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_elt_get_from_name(WBXMLTreeNode *node, + const char *name, + WB_BOOL recurs); + +#if defined ( WBXML_SUPPORT_SYNCML ) + +/** + * @brief Get the SyncML Data Type of this Tree Node + * @param node The Tree Node + * @return The SyncML Data Type of this Tree Node (cf: WBXMLSyncMLDataType enum) + * @note If no specific Data Type is found, this function returns 'WBXML_SYNCML_DATA_TYPE_NORMAL' + */ +WBXML_DECLARE(WBXMLSyncMLDataType) wbxml_tree_node_get_syncml_data_type(WBXMLTreeNode *node); + +#endif /* WBXML_SUPPORT_SYNCML */ + +/** + * @brief Check if a node have an Element Node in its children list + * @param node The Tree Node + * @return YES if one of the node children is an Element, FALSE otherwise + */ +WBXML_DECLARE(WB_BOOL) wbxml_tree_node_have_child_elt(WBXMLTreeNode *node); + +/** + * @brief Get all children from node + * @param node The Tree Node + * @return A list of all children belonging to this node, or NULL if no children found + */ +WBXML_DECLARE(WBXMLList*) wbxml_tree_node_get_all_children(WBXMLTreeNode *node); + + +/** + * @brief Create a Tree structure + * @param lang Tree Language + * @param orig_charset Original tree charset + * @return The newly created Tree, or NULL if not enough memory + * @note The 'orig_charset' is used for further Tree encoding, it does NOT set + * the internal Tree representation charset (UTF8 is always used). + */ +WBXML_DECLARE(WBXMLTree *) wbxml_tree_create(WBXMLLanguage lang, + WBXMLCharsetMIBEnum orig_charset); + +/** + * @brief Destroy a Tree structure, and all its nodes + * @param tree The Tree structure to destroy + */ +WBXML_DECLARE(void) wbxml_tree_destroy(WBXMLTree *tree); + +/** + * @brief Add a Node to a Tree + * @param tree The Tree to modify + * @param parent Parent of the new Node (ie: Position where to add the new Node in Tree) + * @param node The new Tree Node to add + * @return TRUE is added, or FALSE if error. + * @note If 'parent' is NULL: if 'tree' already have a Root Element this function returns FALSE, else 'node' becomes the Root Element of 'tree' + */ +WBXML_DECLARE(WB_BOOL) wbxml_tree_add_node(WBXMLTree *tree, + WBXMLTreeNode *parent, + WBXMLTreeNode *node); + +/** + * @brief Extract a Tree Node from its WBXML Tree + * @param tree The Tree to modify + * @param node The Tree Node to extract + * @return WBXML_OK if no error, an error code otherwise + * @note The node is extracted but not freed + */ +WBXML_DECLARE(WBXMLError) wbxml_tree_extract_node(WBXMLTree *tree, + WBXMLTreeNode *node); + +/** + * @brief Add an Element Node to Tree, given its WBXML Tag + * @param tree The Tree to modify + * @param parent Parent of the new Node (ie: Position where to add the new Node in Tree) + * @param tag Element to add + * @return The newly created node, or NULL if error. + * @note If 'parent' is NULL: if 'tree' already have a Root Element this function returns NULL, else 'node' becomes the Root Element of 'tree' + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_elt(WBXMLTree *tree, + WBXMLTreeNode *parent, + WBXMLTag *tag); + +/** + * @brief Add a Tag Element Node to Tree, with its WBXML Attributes + * @param tree The Tree to modify + * @param parent Parent of the new Node (ie: Position where to add the new Node in Tree) + * @param tag Element to add + * @param attrs Element attributes + * @return The newly created node, or NULL if error. + * @note If 'parent' is NULL: if 'tree' already have a Root Element this function returns NULL, else 'node' becomes the Root Element of 'tree' + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_elt_with_attrs(WBXMLTree *tree, + WBXMLTreeNode *parent, + WBXMLTag *tag, + WBXMLAttribute **attrs); + +/** + * @brief Add an Element Node to a Tree, given its XML Name + * @param tree The Tree to modify + * @param parent Parent of the new Node (ie: Position where to add the new Node in Tree) + * @param name XML element name to add + * @return The newly created node, or NULL if error. + * @note If 'parent' is NULL: if 'tree' already have a Root Element this function returns NULL, else 'node' becomes the Root Element of 'tree' + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_xml_elt(WBXMLTree *tree, + WBXMLTreeNode *parent, + WB_UTINY *name); + +/** + * @brief Add an Element Node to Tree, with its WBXML Attributes, given there XML values + * @param tree The Tree to modify + * @param parent Parent of the new Node (ie: Position where to add the new Node in Tree) + * @param name XML element name to add + * @param attrs XML element attributes + * @return The newly created node, or NULL if error. + * @note If 'parent' is NULL: if 'tree' already have a Root Element this function returns NULL, else 'node' becomes the Root Element of 'tree' + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_xml_elt_with_attrs(WBXMLTree *tree, + WBXMLTreeNode *parent, + WB_UTINY *name, + const WB_UTINY **attrs); + +/** + * @brief Add a Text Node to Tree + * @param tree The Tree to modify + * @param parent Parent of the new Node (ie: Position where to add the new Node in Tree) + * @param text Text to add + * @param len Text length + * @return The newly created node, or NULL if error. + * @note If 'parent' is NULL: if 'tree' already have a Root Element this function returns NULL, else 'node' becomes the Root Element of 'tree' + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_text(WBXMLTree *tree, + WBXMLTreeNode *parent, + const WB_UTINY *text, + WB_ULONG len); + +/** + * @brief Add CDATA Node to Tree + * @param tree The Tree to modify + * @param parent Parent of the new Node (ie: Position where to add the new Node in Tree) + * @return The newly created node, or NULL if error. + * @note If 'parent' is NULL: if 'tree' already have a Root Element this function returns NULL, else 'node' becomes the Root Element of 'tree' + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_cdata(WBXMLTree *tree, + WBXMLTreeNode *parent); + +/** @todo wbxml_tree_add_cdata_with_text() */ + +/** + * @brief Add a Tree Node to Tree + * @param tree The Tree to modify + * @param parent Parent of the new Node (ie: Position where to add the new Node in Tree) + * @param new_tree The new Tree to add (will be freed when destroying the main Tree, so caller must not free it) + * @return The newly created node, or NULL if error. + * @note If 'parent' is NULL: if 'tree' already have a Root Element this function returns NULL, else 'node' becomes the Root Element of 'tree' + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_tree(WBXMLTree *tree, + WBXMLTreeNode *parent, + WBXMLTree *new_tree); + +/** + * @brief Add an Element Node to a Tree, given its XML Name, its attributes and a text content + * @param tree The Tree to modify + * @param parent Parent of the new Node (ie: Position where to add the new Node in Tree) + * @param name XML element name to add + * @param attrs XML element attributes + * @param text Text content for this new element + * @param len Text content length + * @return The newly created node, or NULL if error. + * @note If 'parent' is NULL: if 'tree' already have a Root Element this function returns NULL, else 'node' becomes the Root Element of 'tree' + */ +WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_add_xml_elt_with_attrs_and_text(WBXMLTree *tree, + WBXMLTreeNode *parent, + WB_UTINY *name, + const WB_UTINY **attrs, + const WB_UTINY *text, + WB_ULONG len); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_TREE_H */ diff --git a/src/wbxml_tree_clb_wbxml.c b/src/wbxml_tree_clb_wbxml.c new file mode 100644 index 0000000..5586335 --- /dev/null +++ b/src/wbxml_tree_clb_wbxml.c @@ -0,0 +1,226 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_tree_clb_wbxml.c + * @ingroup wbxml_tree + * + * @author Aymerick Jehanne + * @date 03/02/22 + * + * @brief WBXML Tree Callbacks for WBXML Parser + */ + +#include "wbxml_tree_clb_wbxml.h" +#include "wbxml_tree.h" + + +/*************************************************** + * Public Functions + */ + +void wbxml_tree_clb_wbxml_start_document(void *ctx, WBXMLCharsetMIBEnum charset, const WBXMLLangEntry *lang) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + + if (tree_ctx->error != WBXML_OK) + return; + + tree_ctx->tree->lang = lang; + tree_ctx->tree->orig_charset = charset; +} + + +void wbxml_tree_clb_wbxml_end_document(void *ctx) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + + if (tree_ctx->error != WBXML_OK) + return; +} + + +void wbxml_tree_clb_wbxml_start_element(void *ctx, WBXMLTag *element, WBXMLAttribute **attrs, WB_BOOL empty) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + + (void) empty; /* avoid warning about unused parameter */ + + if (tree_ctx->error != WBXML_OK) + return; + + /* Add a new Node to tree */ + tree_ctx->current = wbxml_tree_add_elt_with_attrs(tree_ctx->tree, + tree_ctx->current, + element, + attrs); + if (tree_ctx->current == NULL) { + tree_ctx->error = WBXML_ERROR_INTERNAL; + } +} + + +void wbxml_tree_clb_wbxml_end_element(void *ctx, WBXMLTag *element, WB_BOOL empty) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + + (void) empty; /* avoid warning about unused parameter */ + + if (tree_ctx->error != WBXML_OK) + return; + + if (tree_ctx->current == NULL) { + tree_ctx->error = WBXML_ERROR_INTERNAL; + return; + } + + if (tree_ctx->current->parent == NULL) { + /* This must be the Root Element */ + if (tree_ctx->current != tree_ctx->tree->root) { + tree_ctx->error = WBXML_ERROR_INTERNAL; + } + } + else { +#if defined ( WBXML_SUPPORT_SYNCML ) + /* Have we added a CDATA section ? + * If so, we assume that now that we have reached an end of Element, + * the CDATA section ended, and so we go back to parent. + */ + if ((tree_ctx->current != NULL) && (tree_ctx->current->type == WBXML_TREE_CDATA_NODE)) + tree_ctx->current = tree_ctx->current->parent; +#endif /* WBXML_SUPPORT_SYNCML */ + + /* Go back one step upper in the tree */ + tree_ctx->current = tree_ctx->current->parent; + } +} + + +void wbxml_tree_clb_wbxml_characters(void *ctx, WB_UTINY *ch, WB_ULONG start, WB_ULONG length) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; +#if defined ( WBXML_SUPPORT_SYNCML ) + WBXMLTree *tmp_tree = NULL; +#endif /* WBXML_SUPPORT_SYNCML */ + + if (tree_ctx->error != WBXML_OK) + return; + +#if defined ( WBXML_SUPPORT_SYNCML ) + /* Specific treatment for SyncML */ + switch (wbxml_tree_node_get_syncml_data_type(tree_ctx->current)) { + case WBXML_SYNCML_DATA_TYPE_WBXML: + /* Deal with Embedded SyncML Documents - Parse WBXML */ + if (wbxml_tree_from_wbxml(ch + start, length, WBXML_LANG_UNKNOWN, tree_ctx->tree->orig_charset, &tmp_tree) != WBXML_OK) { + /* Not parsable ? Just add it as a Text Node... */ + goto text_node; + } + + /* Add Tree Node */ + if (wbxml_tree_add_tree(tree_ctx->tree, + tree_ctx->current, + tmp_tree) == NULL) + { + tree_ctx->error = WBXML_ERROR_INTERNAL; + wbxml_tree_destroy(tmp_tree); + } + + /* Return !! */ + return; + break; + + case WBXML_SYNCML_DATA_TYPE_CLEAR: + case WBXML_SYNCML_DATA_TYPE_DIRECTORY_VCARD: + case WBXML_SYNCML_DATA_TYPE_VCALENDAR: + case WBXML_SYNCML_DATA_TYPE_VCARD: + case WBXML_SYNCML_DATA_TYPE_VOBJECT: + /* + * Add a CDATA section node + * + * Example: + * + * 6 + * text/x-vcard + * + * + * pas-id-3F4B790300000000 + * + * + * + * + * + * + * The end of CDATA section is assumed to be reached when parsing the end + * of element. + */ + + /* Add new CDATA Node */ + tree_ctx->current = wbxml_tree_add_cdata(tree_ctx->tree, tree_ctx->current); + if (tree_ctx->current == NULL) { + tree_ctx->error = WBXML_ERROR_INTERNAL; + return; + } + + /* Now we can add the Text Node */ + break; + + default: + /* NOP */ + break; + } /* switch */ + +text_node: + +#endif /* WBXML_SUPPORT_SYNCML */ + + /* Add Text Node */ + if (wbxml_tree_add_text(tree_ctx->tree, + tree_ctx->current, + (const WB_UTINY*) ch + start, + length) == NULL) + { + tree_ctx->error = WBXML_ERROR_INTERNAL; + } +} + + +void wbxml_tree_clb_wbxml_pi(void *ctx, const WB_UTINY *target, WB_UTINY *data) +{ + /** @todo wbxml_tree_clb_pi() */ +} diff --git a/src/wbxml_tree_clb_wbxml.h b/src/wbxml_tree_clb_wbxml.h new file mode 100644 index 0000000..b2738f9 --- /dev/null +++ b/src/wbxml_tree_clb_wbxml.h @@ -0,0 +1,105 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_tree_clb_wbxml.h + * @ingroup wbxml_tree + * + * @author Aymerick Jehanne + * @date 03/02/22 + * + * @brief WBXML Tree Callbacks for WBXML Parser + */ + +#ifndef WBXML_TREE_CLB_WBXML_H +#define WBXML_TREE_CLB_WBXML_H + +#include "wbxml.h" +#include "wbxml_elt.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_tree + * @{ + */ + +/** + * @brief Start Document Callback + * @param ctx User data + * @param charset Charset (IANA code) + * @param lang Language Table for this Document (cf: wbxml_table.[h|c]) + */ +void wbxml_tree_clb_wbxml_start_document(void *ctx, WBXMLCharsetMIBEnum charset, const WBXMLLangEntry *lang); + +/** + * @brief End Document Callback + * @param ctx User data + */ +void wbxml_tree_clb_wbxml_end_document(void *ctx); + +/** + * @brief Start Element Callback + * @param ctx User data + * @param element The Tag Element + * @param atts The attributes attached to the element + * @param empty Set to TRUE if this is an empty element + */ +void wbxml_tree_clb_wbxml_start_element(void *ctx, WBXMLTag *element, WBXMLAttribute **atts, WB_BOOL empty); + +/** + * @brief End Element Callback + * @param ctx User data + * @param element The Tag Element + * @param empty Set to TRUE if this is an empty element + */ +void wbxml_tree_clb_wbxml_end_element(void *ctx, WBXMLTag *element, WB_BOOL empty); + +/** + * @brief Characters Callback + * @param ctx User data + * @param ch The characters + * @param start The start position in the array + * @param length The number of characters to read from the array + */ +void wbxml_tree_clb_wbxml_characters(void *ctx, WB_UTINY *ch, WB_ULONG start, WB_ULONG length); + +/** + * @brief Processing Instruction Callback + * @param ctx User data + * @param target The processing instruction target. + * @param data The processing instruction data, or null if none was supplied. The data does + * not include any whitespace separating it from the target + */ +void wbxml_tree_clb_wbxml_pi(void *ctx, const WB_UTINY *target, WB_UTINY *data); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* WBXML_TREE_CLB_WBXML_H */ diff --git a/src/wbxml_tree_clb_xml.c b/src/wbxml_tree_clb_xml.c new file mode 100644 index 0000000..77ed42d --- /dev/null +++ b/src/wbxml_tree_clb_xml.c @@ -0,0 +1,636 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2008-2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_tree_clb_xml.c + * @ingroup wbxml_tree + * + * @author Aymerick Jehanne + * @date 03/03/11 + * + * @brief WBXML Tree Callbacks for XML Parser (Expat) + */ + +#include "wbxml_config_internals.h" + +#if defined( HAVE_EXPAT ) + +#include "wbxml_tree_clb_xml.h" +#include "wbxml_tree.h" +#include "wbxml_log.h" +#include "wbxml_charset.h" +#include "wbxml_base64.h" + +/************************************ + * Public Functions + */ + +void wbxml_tree_clb_xml_decl(void *ctx, + const XML_Char *version, + const XML_Char *encoding, + int standalone) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + + (void) standalone; /* avoid warning about unused parameter */ + + if (tree_ctx->expat_utf16) { + /** @todo Convert from UTF-16 to UTF-8 */ + } + + /* This handler is called for XML declarations and also for text declarations discovered + * in external entities. The way to distinguish is that the version parameter will + * be NULL for text declarations. + */ + if (version != NULL) { + if (encoding != NULL) { + /* Get encoding */ + if (!wbxml_charset_get_mib((const WB_TINY*)encoding, &(tree_ctx->tree->orig_charset))) { + WBXML_WARNING((WBXML_CONV, "Charset Encoding not supported: %s", encoding)); + } + } + } +} + + +void wbxml_tree_clb_xml_doctype_decl(void *ctx, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + const WBXMLLangEntry *lang_table = NULL; + + (void) doctypeName; /* avoid warning about unused parameter */ + (void) has_internal_subset; /* avoid warning about unused parameter */ + + if (tree_ctx->expat_utf16) { + /** @todo Convert from UTF-16 to UTF-8 */ + } + + /* Search for Language Table, given the XML Public ID and System ID */ + lang_table = wbxml_tables_search_table(wbxml_tables_get_main(), + (const WB_UTINY *) pubid, + (const WB_UTINY *) sysid, + NULL); + + if (lang_table != NULL) { + /* Ho Yeah ! We got it ! */ + tree_ctx->tree->lang = lang_table; + } + else { + /* We will try to find the Language Table, given the Root Element */ + WBXML_WARNING((WBXML_CONV, "Language Table NOT found, given the XML Public ID and System ID")); + } +} + + +void wbxml_tree_clb_xml_start_element(void *ctx, + const XML_Char *localName, + const XML_Char **attrs) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + const WBXMLLangEntry *lang_table = NULL; + + WBXML_DEBUG((WBXML_PARSER, "Expat element start callback ('%s')", localName)); + + if (tree_ctx->expat_utf16) { + /** @todo Convert from UTF-16 to UTF-8 */ + } + + /* Check for Error */ + if (tree_ctx->error != WBXML_OK) + return; + + /* Are we skipping a whole node ? */ + if (tree_ctx->skip_lvl > 0) { + tree_ctx->skip_lvl++; + return; + } + + if (tree_ctx->current == NULL) { + /* This is the Root Element */ + if (tree_ctx->tree->lang == NULL) { + /* Language Table not already found: Search again */ + lang_table = wbxml_tables_search_table(wbxml_tables_get_main(), + NULL, + NULL, + (const WB_UTINY *) localName); + + if (lang_table == NULL) { + /* Damn, this is an unknown language for us... */ + tree_ctx->error = WBXML_ERROR_UNKNOWN_XML_LANGUAGE; + return; + } + else { + /* Well, we hope this was the Language we are searching for.. let's try with it :| */ + tree_ctx->tree->lang = lang_table; + } + } + } + +#if defined( WBXML_SUPPORT_SYNCML ) + + /* If this is an embedded (not root) document, skip it + * Actually SyncML DevInf and DM DDF are known as such + * potentially embedded documents. + */ + if (( + (WBXML_STRCMP(localName, "syncml:devinf:DevInf") == 0) || + (WBXML_STRCMP(localName, "syncml:dmddf1.2:MgmtTree") == 0) + )&& + (tree_ctx->current != NULL)) + { + tree_ctx->skip_start = XML_GetCurrentByteIndex(tree_ctx->xml_parser); + + /* Skip this node */ + tree_ctx->skip_lvl++; + + return; + } + +#endif /* WBXML_SUPPORT_SYNCML */ + + /* Add Element Node */ + tree_ctx->current = wbxml_tree_add_xml_elt_with_attrs(tree_ctx->tree, + tree_ctx->current, + (WB_UTINY *) localName, + (const WB_UTINY**) attrs); + + if (tree_ctx->current == NULL) { + tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + } +} + + +void wbxml_tree_clb_xml_end_element(void *ctx, + const XML_Char *localName) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; +#if defined( WBXML_SUPPORT_SYNCML ) + WBXMLBuffer *embed_doc = NULL; + WBXMLBuffer *content = NULL; + WBXMLTree *tree = NULL; + WBXMLTreeNode *node = NULL; + WBXMLError ret = WBXML_OK; +#endif /* WBXML_SUPPORT_SYNCML */ + + WBXML_DEBUG((WBXML_PARSER, "Expat element end callback ('%s')", localName)); + + /* If the node is flagged as binary node + * then the data is base64 encoded in the XML document + * and the data must be decoded in one step. + */ + + node = tree_ctx->current; + if (node && node->type == WBXML_TREE_ELEMENT_NODE && + node->name->type == WBXML_VALUE_TOKEN && + node->name->u.token->options & WBXML_TAG_OPTION_BINARY) + { + if (node->content == NULL) + { + WBXML_DEBUG((WBXML_PARSER, " Binary tag: No content => no conversion!")); + } else { + WBXML_DEBUG((WBXML_PARSER, " Binary tag: Convert base64 data")); + ret = wbxml_buffer_decode_base64(node->content); + if (ret != WBXML_OK) + { + WBXML_DEBUG((WBXML_PARSER, " Binary tag: Base64 decoder failed!")); + tree_ctx->error = ret; + } else { + /* Add the buffer as a regular string node (since libwbxml doesn't + * offer a way to specify an opaque data node). The WBXML + * encoder is responsible for generating correct opaque data for + * nodes like this. + */ + if (wbxml_tree_add_text(tree_ctx->tree, + tree_ctx->current, + (const WB_UTINY*)wbxml_buffer_get_cstr(node->content), + wbxml_buffer_len(node->content)) == NULL) + { + WBXML_DEBUG((WBXML_PARSER, " Binary tag: Cannot add base64 decoded node!")); + tree_ctx->error = WBXML_ERROR_INTERNAL; + } + } + /* safe cleanup */ + content = node->content; + node->content = NULL; + wbxml_buffer_destroy(content); + } + } + + if (tree_ctx->expat_utf16) { + /** @todo Convert from UTF-16 to UTF-8 */ + } + + /* Check for Error */ + if (tree_ctx->error != WBXML_OK) + return; + + /* Are we skipping a whole node ? */ + if (tree_ctx->skip_lvl > 0) { + if (tree_ctx->skip_lvl == 1) + { + /* End of skipped node */ + +#if defined( WBXML_SUPPORT_SYNCML ) + if (WBXML_STRCMP(localName, "syncml:devinf:DevInf") == 0 || + WBXML_STRCMP(localName, "syncml:dmddf1.2:MgmtTree") == 0) { + /* definitions first ... or some compilers don't like it */ + const WBXMLLangEntry *lang; + + /* Get embedded DevInf or DM DDF Document */ + embed_doc = wbxml_buffer_create(tree_ctx->input_buff + tree_ctx->skip_start, + XML_GetCurrentByteIndex(tree_ctx->xml_parser) - tree_ctx->skip_start, + XML_GetCurrentByteIndex(tree_ctx->xml_parser) - tree_ctx->skip_start + 10); + if (embed_doc == NULL) { + tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + wbxml_buffer_destroy(embed_doc); + return; + } + + if (tree_ctx->expat_utf16) { + /** @todo Convert from UTF-16 to UTF-8 */ + } + + /* Check Buffer Creation and add the closing tag */ + if ((WBXML_STRCMP(localName, "syncml:devinf:DevInf") == 0 && + (!wbxml_buffer_append_cstr(embed_doc, ""))) + || + (WBXML_STRCMP(localName, "syncml:dmddf1.2:MgmtTree") == 0 && + (!wbxml_buffer_append_cstr(embed_doc, "")))) + { + tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + wbxml_buffer_destroy(embed_doc); + return; + } + + /* Add doctype to give the XML parser a chance */ + if (WBXML_STRCMP(localName, "syncml:dmddf1.2:MgmtTree") == 0 && + tree_ctx->tree->lang->langID != WBXML_LANG_SYNCML_SYNCML12) + { + tree_ctx->error = WBXML_ERROR_UNKNOWN_XML_LANGUAGE; + wbxml_buffer_destroy(embed_doc); + return; + } + switch(tree_ctx->tree->lang->langID) + { + case WBXML_LANG_SYNCML_SYNCML10: + lang = wbxml_tables_get_table(WBXML_LANG_SYNCML_DEVINF10); + break; + case WBXML_LANG_SYNCML_SYNCML11: + lang = wbxml_tables_get_table(WBXML_LANG_SYNCML_DEVINF11); + break; + case WBXML_LANG_SYNCML_SYNCML12: + if (WBXML_STRCMP(localName, "syncml:dmddf1.2:MgmtTree") == 0) { + lang = wbxml_tables_get_table(WBXML_LANG_SYNCML_DMDDF12); + } else { + lang = wbxml_tables_get_table(WBXML_LANG_SYNCML_DEVINF12); + } + break; + default: + tree_ctx->error = WBXML_ERROR_UNKNOWN_XML_LANGUAGE; + return; + } + + /* DOCTYPE in reverse order */ + if (!wbxml_buffer_insert_cstr(embed_doc,(WB_UTINY *) "\">\n", 0) || /* > */ + !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) lang->publicID->xmlDTD, 0) || /* DTD */ + !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) "\" \"", 0) || /* DTD */ + !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) lang->publicID->xmlPublicID, 0) || /* Public ID */ + !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) " PUBLIC \"", 0) || /* PUBLIC " */ + !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) lang->publicID->xmlRootElt, 0) || /* Root Element */ + !wbxml_buffer_insert_cstr(embed_doc, (WB_UTINY *) "error = WBXML_ERROR_ENCODER_APPEND_DATA; + wbxml_buffer_destroy(embed_doc); + return; + } + + WBXML_DEBUG((WBXML_PARSER, "\t Embedded Doc : '%s'", wbxml_buffer_get_cstr(embed_doc))); + + /* Parse 'DevInf' Document */ + if ((ret = wbxml_tree_from_xml(wbxml_buffer_get_cstr(embed_doc), + wbxml_buffer_len(embed_doc), + &tree)) != WBXML_OK) + { + tree_ctx->error = ret; + wbxml_buffer_destroy(embed_doc); + return; + } + + /* Add Tree Node */ + tree_ctx->current = wbxml_tree_add_tree(tree_ctx->tree, + tree_ctx->current, + tree); + if (tree_ctx->current == NULL) + { + tree_ctx->error = WBXML_ERROR_INTERNAL; + wbxml_tree_destroy(tree); + wbxml_buffer_destroy(embed_doc); + return; + } + + /* Clean-up */ + wbxml_buffer_destroy(embed_doc); + tree_ctx->skip_lvl = 0; + } +#endif /* WBXML_SUPPORT_SYNCML */ + } + else { + tree_ctx->skip_lvl--; + return; + } + } + + if (tree_ctx->current == NULL) { + tree_ctx->error = WBXML_ERROR_INTERNAL; + return; + } + + if (tree_ctx->current->parent == NULL) { + /* This must be the Root Element */ + if (tree_ctx->current != tree_ctx->tree->root) { + tree_ctx->error = WBXML_ERROR_INTERNAL; + } + } + else { +#if defined ( WBXML_SUPPORT_SYNCML ) + /* Have we added a missing CDATA section ? + * If so, we assume that now that we have reached an end of Element, + * the CDATA section ended, and so we go back to parent. + */ + if ((tree_ctx->current != NULL) && (tree_ctx->current->type == WBXML_TREE_CDATA_NODE)) + tree_ctx->current = tree_ctx->current->parent; +#endif /* WBXML_SUPPORT_SYNCML */ + + /* Go back one step upper in the tree */ + tree_ctx->current = tree_ctx->current->parent; + } +} + + +void wbxml_tree_clb_xml_start_cdata(void *ctx) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + + /* Check for Error */ + if (tree_ctx->error != WBXML_OK) + return; + + /* Are we skipping a whole node ? */ + if (tree_ctx->skip_lvl > 0) + return; + + /* Add CDATA Node */ + tree_ctx->current = wbxml_tree_add_cdata(tree_ctx->tree, tree_ctx->current); + if (tree_ctx->current == NULL) { + tree_ctx->error = WBXML_ERROR_INTERNAL; + } +} + + +void wbxml_tree_clb_xml_end_cdata(void *ctx) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + + /* Check for Error */ + if (tree_ctx->error != WBXML_OK) + return; + + /* Are we skipping a whole node ? */ + if (tree_ctx->skip_lvl > 0) + return; + + if (tree_ctx->current == NULL) { + tree_ctx->error = WBXML_ERROR_INTERNAL; + return; + } + + if (tree_ctx->current->parent == NULL) { + /* This must be the Root Element */ + if (tree_ctx->current != tree_ctx->tree->root) { + tree_ctx->error = WBXML_ERROR_INTERNAL; + } + } + else { + /* Go back one step upper in the tree */ + tree_ctx->current = tree_ctx->current->parent; + } +} + + +void wbxml_tree_clb_xml_characters(void *ctx, + const XML_Char *ch, + int len) +{ + WBXMLTreeNode *node; + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + + WBXML_DEBUG((WBXML_PARSER, "Expat text callback")); + + if (tree_ctx->expat_utf16) { + /** @todo Convert from UTF-16 to UTF-8 */ + } + + /* Check for Error */ + if (tree_ctx->error != WBXML_OK) + return; + + /* Are we skipping a whole node ? */ + if (tree_ctx->skip_lvl > 0) + return; + +#if defined ( WBXML_SUPPORT_SYNCML ) + /* Specific treatment for SyncML */ + switch (wbxml_tree_node_get_syncml_data_type(tree_ctx->current)) { + case WBXML_SYNCML_DATA_TYPE_DIRECTORY_VCARD: + case WBXML_SYNCML_DATA_TYPE_VCALENDAR: + case WBXML_SYNCML_DATA_TYPE_VCARD: + case WBXML_SYNCML_DATA_TYPE_VOBJECT: + /* SyncML has some real design bugs + * because the authors of the specification did not understand XML. + * + * There must be a hack to preserve the CRLFs of vFormat objects. + * The only chance to do this is the detection of the vFormat itself + * and the conversion of every LF to a CRLF. + * + * The line breaks are always in a single text node. + * So a CR is appended to get a CRLF at the end. + */ + + if (len == 1 && ch[0] == '\n') /* line break - LF */ + { + ch = "\r\n"; + len = 2; + } + + /* Do not break here. + * The CDATA handling is required for vFormat objects too. + */ + case WBXML_SYNCML_DATA_TYPE_CLEAR: + /* + * Add a missing CDATA section node + * + * Example: + * + * 6 + * text/x-vcard + * + * + * pas-id-3F4B790300000000 + * + * BEGIN:VCARD + * VERSION:2.1 + * X-EVOLUTION-FILE-AS:Ximian, Inc. + * N: + * LABEL;WORK;ENCODING=QUOTED-PRINTABLE:401 Park Drive 3 West=0ABoston, MA + * 02215=0AUSA + * TEL;WORK;VOICE:(617) 236-0442 + * TEL;WORK;FAX:(617) 236-8630 + * EMAIL;INTERNET:[EMAIL PROTECTED] + * URL:www.ximian.com/ + * ORG:Ximian, Inc. + * NOTE:Welcome to the Ximian Addressbook. + * UID:pas-id-3F4B790300000000 + * END:VCARD + * + * + * + * The end of CDATA section is assumed to be reached when parsing the end + * of element. + * + * This kind of document is erroneous, but we must handle it. + * Normally, this should be: + * + * ... + * + * ... + */ + + /* + * We add a missing CDATA section if we are not already in a CDATA section. + * + * We don't add a CDATA section if we have already added a CDATA section. This + * permits to correctly handle good XML documents like this: + * + * ... + * + * + * ... + * + * In this example, the spaces beetwen "]]>" and "" must not be added + * to a CDATA section. + */ + if ((tree_ctx->current != NULL) && + (tree_ctx->current->type != WBXML_TREE_CDATA_NODE) && + !((tree_ctx->current->children != NULL) && + (tree_ctx->current->children->type == WBXML_TREE_CDATA_NODE))) + { + /* Add CDATA Node */ + tree_ctx->current = wbxml_tree_add_cdata(tree_ctx->tree, tree_ctx->current); + if (tree_ctx->current == NULL) { + tree_ctx->error = WBXML_ERROR_INTERNAL; + return; + } + } + + /* Now we can add the Text Node */ + break; + + default: + /* NOP */ + break; + } /* switch */ +#endif /* WBXML_SUPPORT_SYNCML */ + + /* We expect that "byte array" or BLOB types are + * encoded in Base 64 in the XML code, since they may contain binary data. + */ + + node = tree_ctx->current; + if (node && node->type == WBXML_TREE_ELEMENT_NODE && + node->name->type == WBXML_VALUE_TOKEN && + node->name->u.token->options & WBXML_TAG_OPTION_BINARY) + { + WBXML_DEBUG((WBXML_PARSER, " Binary tag: Caching base64 encoded data for later conversion.")); + if (node->content == NULL) + { + node->content = wbxml_buffer_create(ch, len, 1); + if (node->content == NULL) + tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + } else { + if (!wbxml_buffer_append_data(node->content, ch, len)) + tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY; + } + return; + } + + /* Add Text Node */ + if (wbxml_tree_add_text(tree_ctx->tree, + tree_ctx->current, + (const WB_UTINY*) ch, + len) == NULL) + { + tree_ctx->error = WBXML_ERROR_INTERNAL; + } +} + + +void wbxml_tree_clb_xml_pi(void *ctx, + const XML_Char *target, + const XML_Char *data) +{ + WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx; + + if (tree_ctx->expat_utf16) { + /** @todo Convert from UTF-16 to UTF-8 */ + } + + /* Check for Error */ + if (tree_ctx->error != WBXML_OK) + return; + + /* Are we skipping a whole node ? */ + if (tree_ctx->skip_lvl > 0) + return; + + /** @todo wbxml2xml_clb_pi() */ +} + +#endif /* HAVE_EXPAT */ diff --git a/src/wbxml_tree_clb_xml.h b/src/wbxml_tree_clb_xml.h new file mode 100644 index 0000000..befea53 --- /dev/null +++ b/src/wbxml_tree_clb_xml.h @@ -0,0 +1,126 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml_tree_clb_xml.h + * @ingroup wbxml_tree + * + * @author Aymerick Jehanne + * @date 03/03/11 + * + * @brief WBXML Tree Callbacks for XML Parser (Expat) + */ + +#ifndef WBXML_TREE_CLB_XML_H +#define WBXML_TREE_CLB_XML_H + +#include "wbxml.h" +#include + +#if defined( HAVE_EXPAT ) + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup wbxml_tree + * @{ + */ + +/** + * @brief XML Declarations Callback + * @param ctx User data + * @param version XML version + * @param encoding XML encoding + * @param standalone Value -1, 0, or 1 indicating respectively that there was no standalone parameter in the declaration, that it was given as no, or that it was given as yes. + */ +void wbxml_tree_clb_xml_decl(void *ctx, const XML_Char *version, + const XML_Char *encoding, int standalone); + +/** + * @brief Doctype Declaration Callback + * @param ctx User data + * @param doctypeName Doctype Name + * @param sysid System ID + * @param pubid Public ID + * @param has_internal_subset Non-zero if the DOCTYPE declaration has an internal subset + */ +void wbxml_tree_clb_xml_doctype_decl(void *ctx, const XML_Char *doctypeName, + const XML_Char *sysid, const XML_Char *pubid, + int has_internal_subset); + +/** + * @brief Start Element Callback + * @param ctx User data + * @param localName The local tag name + * @param attrs The attributes attached to the element + */ +void wbxml_tree_clb_xml_start_element(void *ctx, const XML_Char *localName, const XML_Char **attrs); + +/** + * @brief End Element Callback + * @param ctx User data + * @param localName The local tag name + */ +void wbxml_tree_clb_xml_end_element(void *ctx, const XML_Char *localName); + +/** + * @brief Start of CDATA Section Callback + * @param ctx User data + */ +void wbxml_tree_clb_xml_start_cdata(void *ctx); + +/** + * @brief End of CDATA Section Callback + * @param ctx User data + */ +void wbxml_tree_clb_xml_end_cdata(void *ctx); + +/** + * @brief Characters Callback + * @param ctx User data + * @param ch The characters array + * @param len The number of characters to read from the array + */ +void wbxml_tree_clb_xml_characters(void *ctx, const XML_Char *ch, int len); + +/** + * @brief Processing Instruction Callback + * @param ctx User data + * @param target The processing instruction target. + * @param data The processing instruction data, or null if none was supplied. The data does + * not include any whitespace separating it from the target + */ +void wbxml_tree_clb_xml_pi(void *ctx, const XML_Char *target, const XML_Char *data); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* HAVE_EXPAT */ + +#endif /* WBXML_TREE_CLB_XML_H */ diff --git a/symbian/LIBWBXML_ARMI.DEF b/symbian/LIBWBXML_ARMI.DEF new file mode 100644 index 0000000..b998b6d --- /dev/null +++ b/symbian/LIBWBXML_ARMI.DEF @@ -0,0 +1,103 @@ +EXPORTS + wbxml_attribute_create @ 1 NONAME + wbxml_attribute_destroy @ 2 NONAME + wbxml_attribute_duplicate @ 3 NONAME + wbxml_attribute_get_xml_name @ 4 NONAME + wbxml_attribute_get_xml_value @ 5 NONAME + wbxml_attribute_name_create @ 6 NONAME + wbxml_attribute_name_create_literal @ 7 NONAME + wbxml_attribute_name_create_token @ 8 NONAME + wbxml_attribute_name_destroy @ 9 NONAME + wbxml_attribute_name_duplicate @ 10 NONAME + wbxml_attribute_name_get_xml_name @ 11 NONAME + wbxml_base64_decode @ 12 NONAME + wbxml_base64_encode @ 13 NONAME + wbxml_buffer_append @ 14 NONAME + wbxml_buffer_append_char @ 15 NONAME + wbxml_buffer_append_cstr_real @ 16 NONAME + wbxml_buffer_append_data_real @ 17 NONAME + wbxml_buffer_append_mb_uint_32 @ 18 NONAME + wbxml_buffer_binary_to_hex @ 19 NONAME + wbxml_buffer_compare @ 20 NONAME + wbxml_buffer_compare_cstr @ 21 NONAME + wbxml_buffer_contains_only_whitespaces @ 22 NONAME + wbxml_buffer_create_real @ 23 NONAME + wbxml_buffer_delete @ 24 NONAME + wbxml_buffer_destroy @ 25 NONAME + wbxml_buffer_destroy_item @ 26 NONAME + wbxml_buffer_duplicate @ 27 NONAME + wbxml_buffer_get_char @ 28 NONAME + wbxml_buffer_get_cstr @ 29 NONAME + wbxml_buffer_hex_to_binary @ 30 NONAME + wbxml_buffer_insert @ 31 NONAME + wbxml_buffer_insert_cstr @ 32 NONAME + wbxml_buffer_len @ 33 NONAME + wbxml_buffer_remove_trailing_zeros @ 34 NONAME + wbxml_buffer_search @ 35 NONAME + wbxml_buffer_search_char @ 36 NONAME + wbxml_buffer_search_cstr @ 37 NONAME + wbxml_buffer_set_char @ 38 NONAME + wbxml_buffer_shrink_blanks @ 39 NONAME + wbxml_buffer_split_words_real @ 40 NONAME + wbxml_buffer_strip_blanks @ 41 NONAME + wbxml_conv_wbxml2xml_withlen @ 42 NONAME + wbxml_conv_xml2wbxml_withlen @ 43 NONAME + wbxml_encoder_create_real @ 44 NONAME + wbxml_encoder_destroy @ 45 NONAME + wbxml_encoder_encode_to_wbxml @ 46 NONAME + wbxml_encoder_encode_to_xml @ 47 NONAME + wbxml_encoder_set_ignore_empty_text @ 48 NONAME + wbxml_encoder_set_indent @ 49 NONAME + wbxml_encoder_set_remove_text_blanks @ 50 NONAME + wbxml_encoder_set_tree @ 51 NONAME + wbxml_encoder_set_use_strtbl @ 52 NONAME + wbxml_encoder_set_wbxml_version @ 53 NONAME + wbxml_encoder_set_xml_gen_type @ 54 NONAME + wbxml_errors_string @ 55 NONAME + wbxml_free @ 56 NONAME + wbxml_list_append @ 57 NONAME + wbxml_list_create_real @ 58 NONAME + wbxml_list_destroy @ 59 NONAME + wbxml_list_extract_first @ 60 NONAME + wbxml_list_get @ 61 NONAME + wbxml_list_insert @ 62 NONAME + wbxml_list_len @ 63 NONAME + wbxml_malloc @ 64 NONAME + wbxml_parser_create @ 65 NONAME + wbxml_parser_destroy @ 66 NONAME + wbxml_parser_get_current_byte_index @ 67 NONAME + wbxml_parser_get_wbxml_public_id @ 68 NONAME + wbxml_parser_get_wbxml_version @ 69 NONAME + wbxml_parser_get_xml_public_id @ 70 NONAME + wbxml_parser_parse @ 71 NONAME + wbxml_parser_set_content_handler @ 72 NONAME + wbxml_parser_set_language @ 73 NONAME + wbxml_parser_set_main_table @ 74 NONAME + wbxml_parser_set_user_data @ 75 NONAME + wbxml_realloc @ 76 NONAME + wbxml_strdup @ 77 NONAME + wbxml_tables_contains_attr_value_from_xml @ 78 NONAME + wbxml_tables_get_attr_from_xml @ 79 NONAME + wbxml_tables_get_ext_from_xml @ 80 NONAME + wbxml_tables_get_main @ 81 NONAME + wbxml_tables_get_tag_from_xml @ 82 NONAME + wbxml_tables_get_wbxml_publicid @ 83 NONAME + wbxml_tables_get_xmlns @ 84 NONAME + wbxml_tables_search_table @ 85 NONAME + wbxml_tag_create @ 86 NONAME + wbxml_tag_create_literal @ 87 NONAME + wbxml_tag_create_token @ 88 NONAME + wbxml_tag_destroy @ 89 NONAME + wbxml_tag_duplicate @ 90 NONAME + wbxml_tag_get_xml_name @ 91 NONAME + wbxml_tree_attribute_create @ 92 NONAME + wbxml_tree_attribute_destroy @ 93 NONAME + wbxml_tree_create @ 94 NONAME + wbxml_tree_destroy @ 95 NONAME + wbxml_tree_from_wbxml @ 96 NONAME + wbxml_tree_from_xml @ 97 NONAME + wbxml_tree_node_elt_get_from_name @ 98 NONAME + wbxml_tree_node_create @ 99 NONAME + wbxml_tree_node_destroy @ 100 NONAME + wbxml_tree_add_node @ 101 NONAME + wbxml_tree_node_get_syncml_data_type @ 102 NONAME diff --git a/symbian/LIBWBXML_WINS.DEF b/symbian/LIBWBXML_WINS.DEF new file mode 100644 index 0000000..b998b6d --- /dev/null +++ b/symbian/LIBWBXML_WINS.DEF @@ -0,0 +1,103 @@ +EXPORTS + wbxml_attribute_create @ 1 NONAME + wbxml_attribute_destroy @ 2 NONAME + wbxml_attribute_duplicate @ 3 NONAME + wbxml_attribute_get_xml_name @ 4 NONAME + wbxml_attribute_get_xml_value @ 5 NONAME + wbxml_attribute_name_create @ 6 NONAME + wbxml_attribute_name_create_literal @ 7 NONAME + wbxml_attribute_name_create_token @ 8 NONAME + wbxml_attribute_name_destroy @ 9 NONAME + wbxml_attribute_name_duplicate @ 10 NONAME + wbxml_attribute_name_get_xml_name @ 11 NONAME + wbxml_base64_decode @ 12 NONAME + wbxml_base64_encode @ 13 NONAME + wbxml_buffer_append @ 14 NONAME + wbxml_buffer_append_char @ 15 NONAME + wbxml_buffer_append_cstr_real @ 16 NONAME + wbxml_buffer_append_data_real @ 17 NONAME + wbxml_buffer_append_mb_uint_32 @ 18 NONAME + wbxml_buffer_binary_to_hex @ 19 NONAME + wbxml_buffer_compare @ 20 NONAME + wbxml_buffer_compare_cstr @ 21 NONAME + wbxml_buffer_contains_only_whitespaces @ 22 NONAME + wbxml_buffer_create_real @ 23 NONAME + wbxml_buffer_delete @ 24 NONAME + wbxml_buffer_destroy @ 25 NONAME + wbxml_buffer_destroy_item @ 26 NONAME + wbxml_buffer_duplicate @ 27 NONAME + wbxml_buffer_get_char @ 28 NONAME + wbxml_buffer_get_cstr @ 29 NONAME + wbxml_buffer_hex_to_binary @ 30 NONAME + wbxml_buffer_insert @ 31 NONAME + wbxml_buffer_insert_cstr @ 32 NONAME + wbxml_buffer_len @ 33 NONAME + wbxml_buffer_remove_trailing_zeros @ 34 NONAME + wbxml_buffer_search @ 35 NONAME + wbxml_buffer_search_char @ 36 NONAME + wbxml_buffer_search_cstr @ 37 NONAME + wbxml_buffer_set_char @ 38 NONAME + wbxml_buffer_shrink_blanks @ 39 NONAME + wbxml_buffer_split_words_real @ 40 NONAME + wbxml_buffer_strip_blanks @ 41 NONAME + wbxml_conv_wbxml2xml_withlen @ 42 NONAME + wbxml_conv_xml2wbxml_withlen @ 43 NONAME + wbxml_encoder_create_real @ 44 NONAME + wbxml_encoder_destroy @ 45 NONAME + wbxml_encoder_encode_to_wbxml @ 46 NONAME + wbxml_encoder_encode_to_xml @ 47 NONAME + wbxml_encoder_set_ignore_empty_text @ 48 NONAME + wbxml_encoder_set_indent @ 49 NONAME + wbxml_encoder_set_remove_text_blanks @ 50 NONAME + wbxml_encoder_set_tree @ 51 NONAME + wbxml_encoder_set_use_strtbl @ 52 NONAME + wbxml_encoder_set_wbxml_version @ 53 NONAME + wbxml_encoder_set_xml_gen_type @ 54 NONAME + wbxml_errors_string @ 55 NONAME + wbxml_free @ 56 NONAME + wbxml_list_append @ 57 NONAME + wbxml_list_create_real @ 58 NONAME + wbxml_list_destroy @ 59 NONAME + wbxml_list_extract_first @ 60 NONAME + wbxml_list_get @ 61 NONAME + wbxml_list_insert @ 62 NONAME + wbxml_list_len @ 63 NONAME + wbxml_malloc @ 64 NONAME + wbxml_parser_create @ 65 NONAME + wbxml_parser_destroy @ 66 NONAME + wbxml_parser_get_current_byte_index @ 67 NONAME + wbxml_parser_get_wbxml_public_id @ 68 NONAME + wbxml_parser_get_wbxml_version @ 69 NONAME + wbxml_parser_get_xml_public_id @ 70 NONAME + wbxml_parser_parse @ 71 NONAME + wbxml_parser_set_content_handler @ 72 NONAME + wbxml_parser_set_language @ 73 NONAME + wbxml_parser_set_main_table @ 74 NONAME + wbxml_parser_set_user_data @ 75 NONAME + wbxml_realloc @ 76 NONAME + wbxml_strdup @ 77 NONAME + wbxml_tables_contains_attr_value_from_xml @ 78 NONAME + wbxml_tables_get_attr_from_xml @ 79 NONAME + wbxml_tables_get_ext_from_xml @ 80 NONAME + wbxml_tables_get_main @ 81 NONAME + wbxml_tables_get_tag_from_xml @ 82 NONAME + wbxml_tables_get_wbxml_publicid @ 83 NONAME + wbxml_tables_get_xmlns @ 84 NONAME + wbxml_tables_search_table @ 85 NONAME + wbxml_tag_create @ 86 NONAME + wbxml_tag_create_literal @ 87 NONAME + wbxml_tag_create_token @ 88 NONAME + wbxml_tag_destroy @ 89 NONAME + wbxml_tag_duplicate @ 90 NONAME + wbxml_tag_get_xml_name @ 91 NONAME + wbxml_tree_attribute_create @ 92 NONAME + wbxml_tree_attribute_destroy @ 93 NONAME + wbxml_tree_create @ 94 NONAME + wbxml_tree_destroy @ 95 NONAME + wbxml_tree_from_wbxml @ 96 NONAME + wbxml_tree_from_xml @ 97 NONAME + wbxml_tree_node_elt_get_from_name @ 98 NONAME + wbxml_tree_node_create @ 99 NONAME + wbxml_tree_node_destroy @ 100 NONAME + wbxml_tree_add_node @ 101 NONAME + wbxml_tree_node_get_syncml_data_type @ 102 NONAME diff --git a/symbian/bld.inf b/symbian/bld.inf new file mode 100644 index 0000000..6d9a8d6 --- /dev/null +++ b/symbian/bld.inf @@ -0,0 +1,5 @@ +PRJ_MMPFILES + +libwbxml.mmp +wbxml2xml.mmp +xml2wbxml.mmp diff --git a/symbian/libwbxml.mmp b/symbian/libwbxml.mmp new file mode 100644 index 0000000..f9adf10 --- /dev/null +++ b/symbian/libwbxml.mmp @@ -0,0 +1,56 @@ +TARGET Libwbxml.dll +TARGETTYPE dll +UID 0x1000008D 0x001FAE0C + +MACRO __SYMBIAN32__ +MACRO HAVE_EXPAT +MACRO WBXML_ENCODER_USE_STRTBL +MACRO WBXML_SUPPORT_SYNCML +MACRO WBXML_SUPPORT_WML +MACRO WBXML_SUPPORT_WTA +MACRO WBXML_SUPPORT_SI +MACRO WBXML_SUPPORT_SL +MACRO WBXML_SUPPORT_CO +MACRO WBXML_SUPPORT_PROV +MACRO WBXML_SUPPORT_EMN +MACRO WBXML_SUPPORT_DRMREL +MACRO WBXML_SUPPORT_OTA_SETTINGS +MACRO WBXML_SUPPORT_WV + +SOURCEPATH ..\src +SOURCE wbxml_base64.c +SOURCE wbxml_buffers.c +SOURCE wbxml_charset.c +SOURCE wbxml_conv.c +SOURCE wbxml_elt.c +SOURCE wbxml_encoder.c +SOURCE wbxml_errors.c +SOURCE wbxml_lists.c +SOURCE wbxml_log.c +SOURCE wbxml_mem.c +SOURCE wbxml_parser.c +SOURCE wbxml_tables.c +SOURCE wbxml_tree.c +SOURCE wbxml_tree_clb_wbxml.c +SOURCE wbxml_tree_clb_xml.c +SOURCE ..\symbian\libwbxmldll.cpp + +USERINCLUDE . +USERINCLUDE ..\src + +SYSTEMINCLUDE \epoc32\include +SYSTEMINCLUDE \epoc32\include\libc +SYSTEMINCLUDE ..\..\expat\lib + +LIBRARY estlib.lib euser.lib expat.lib +/* +#if defined(WINS) +deffile .\Libwbxml_wins.def +#else +#if defined(ARM) +deffile .\Libwbxml_armi.def +#endif +#endif +nostrictdef +*/ +EXPORTUNFROZEN diff --git a/symbian/libwbxmldll.cpp b/symbian/libwbxmldll.cpp new file mode 100644 index 0000000..e2e7d88 --- /dev/null +++ b/symbian/libwbxmldll.cpp @@ -0,0 +1,8 @@ +#include +#include +#include + +GLDEF_C TInt E32Dll(TDllReason /* aReason */) +{ + return(KErrNone); +} diff --git a/symbian/wbxml2xml.mmp b/symbian/wbxml2xml.mmp new file mode 100644 index 0000000..0644b73 --- /dev/null +++ b/symbian/wbxml2xml.mmp @@ -0,0 +1,31 @@ +TARGET wbxml2xml.exe +TARGETTYPE exe +UID 0 + +MACRO __SYMBIAN32__ +MACRO HAVE_EXPAT +MACRO WBXML_ENCODER_USE_STRTBL +MACRO WBXML_SUPPORT_SYNCML +MACRO WBXML_SUPPORT_WML +MACRO WBXML_SUPPORT_WTA +MACRO WBXML_SUPPORT_SI +MACRO WBXML_SUPPORT_SL +MACRO WBXML_SUPPORT_CO +MACRO WBXML_SUPPORT_PROV +MACRO WBXML_SUPPORT_EMN +MACRO WBXML_SUPPORT_DRMREL +MACRO WBXML_SUPPORT_OTA_SETTINGS +MACRO WBXML_SUPPORT_WV + +SOURCEPATH ..\tools +SOURCE wbxml2xml_tool.c attgetopt.c + +USERINCLUDE . +USERINCLUDE ..\src + +SYSTEMINCLUDE \epoc32\include +SYSTEMINCLUDE \epoc32\include\libc +SYSTEMINCLUDE ..\..\expat\lib + +LIBRARY estlib.lib euser.lib libwbxml.lib +STATICLIBRARY ecrt0.lib diff --git a/symbian/xml2wbxml.mmp b/symbian/xml2wbxml.mmp new file mode 100644 index 0000000..e734c7c --- /dev/null +++ b/symbian/xml2wbxml.mmp @@ -0,0 +1,31 @@ +TARGET xml2wbxml.exe +TARGETTYPE exe +UID 0 + +MACRO __SYMBIAN32__ +MACRO HAVE_EXPAT +MACRO WBXML_ENCODER_USE_STRTBL +MACRO WBXML_SUPPORT_SYNCML +MACRO WBXML_SUPPORT_WML +MACRO WBXML_SUPPORT_WTA +MACRO WBXML_SUPPORT_SI +MACRO WBXML_SUPPORT_SL +MACRO WBXML_SUPPORT_CO +MACRO WBXML_SUPPORT_PROV +MACRO WBXML_SUPPORT_EMN +MACRO WBXML_SUPPORT_DRMREL +MACRO WBXML_SUPPORT_OTA_SETTINGS +MACRO WBXML_SUPPORT_WV + +SOURCEPATH ..\tools +SOURCE xml2wbxml_tool.c attgetopt.c + +USERINCLUDE . +USERINCLUDE ..\src + +SYSTEMINCLUDE \epoc32\include +SYSTEMINCLUDE \epoc32\include\libc +SYSTEMINCLUDE ..\..\expat\lib + +LIBRARY estlib.lib euser.lib libwbxml.lib +STATICLIBRARY ecrt0.lib diff --git a/tests/activesync/activesync-001-settings_device_information.xml b/tests/activesync/activesync-001-settings_device_information.xml new file mode 100644 index 0000000..e7010f6 --- /dev/null +++ b/tests/activesync/activesync-001-settings_device_information.xml @@ -0,0 +1,16 @@ + + + + + + 0.11-beta + 1234567890 + Test Device + Linux + de_DE + +49301234567890 + O2 + libwbxml + + + diff --git a/tests/activesync/activesync-002-settings_user_information.xml b/tests/activesync/activesync-002-settings_user_information.xml new file mode 100644 index 0000000..4fca236 --- /dev/null +++ b/tests/activesync/activesync-002-settings_user_information.xml @@ -0,0 +1,16 @@ + + + + + + 0.11-beta + 1234567890 + Test Device + Linux + de_DE + +49301234567890 + O2 + libwbxml + + + diff --git a/tests/activesync/activesync-003-settings_device_password.xml b/tests/activesync/activesync-003-settings_device_password.xml new file mode 100644 index 0000000..7e73bae --- /dev/null +++ b/tests/activesync/activesync-003-settings_device_password.xml @@ -0,0 +1,16 @@ + + + + + + 0.11-beta + 1234567890 + Test Device + Linux + de_DE + +49301234567890 + O2 + libwbxml + + + diff --git a/tests/activesync/activesync-004-settings_oof.xml b/tests/activesync/activesync-004-settings_oof.xml new file mode 100644 index 0000000..493aca3 --- /dev/null +++ b/tests/activesync/activesync-004-settings_oof.xml @@ -0,0 +1,16 @@ + + + + + + 0.11-beta + 1234567890 + Test Device + Linux + de_DE + +49301234567890 + O2 + libwbxml + + + diff --git a/tests/activesync/activesync-005-settings_status.xml b/tests/activesync/activesync-005-settings_status.xml new file mode 100644 index 0000000..1aa6546 --- /dev/null +++ b/tests/activesync/activesync-005-settings_status.xml @@ -0,0 +1,10 @@ + + + + 1 + + + 1 + + + diff --git a/tests/activesync/activesync-010-provision-eas.xml b/tests/activesync/activesync-010-provision-eas.xml new file mode 100644 index 0000000..814cc25 --- /dev/null +++ b/tests/activesync/activesync-010-provision-eas.xml @@ -0,0 +1,9 @@ + + + + + + MS-EAS-Provisioning-WBXML + + + diff --git a/tests/activesync/activesync-011-provision-wap.xml b/tests/activesync/activesync-011-provision-wap.xml new file mode 100644 index 0000000..2779f43 --- /dev/null +++ b/tests/activesync/activesync-011-provision-wap.xml @@ -0,0 +1,9 @@ + + + + + + MS-WAP-Provisioning-XML + + + diff --git a/tests/activesync/activesync-020-folder_sync_initial_request.xml b/tests/activesync/activesync-020-folder_sync_initial_request.xml new file mode 100644 index 0000000..a0faf96 --- /dev/null +++ b/tests/activesync/activesync-020-folder_sync_initial_request.xml @@ -0,0 +1,6 @@ + + + + 0 + + diff --git a/tests/activesync/activesync-021-folder_sync_initial_response.xml b/tests/activesync/activesync-021-folder_sync_initial_response.xml new file mode 100644 index 0000000..2c9146b --- /dev/null +++ b/tests/activesync/activesync-021-folder_sync_initial_response.xml @@ -0,0 +1,40 @@ + + + + 1 + 1 + + 5 + + 1 + 0 + Calendar + 8 + + + 2 + 0 + Contacts + 9 + + + 3 + 0 + INBOX + 5 + + + 12 + 3 + Family + + 12 + + + RI + 0 + RecipientInfo + 19 + + + diff --git a/tests/activesync/activesync-030-sendmail-request.xml b/tests/activesync/activesync-030-sendmail-request.xml new file mode 100644 index 0000000..af39269 --- /dev/null +++ b/tests/activesync/activesync-030-sendmail-request.xml @@ -0,0 +1,7 @@ + + + + 1 + + RnJvbTogZmFrZXVzZXJAZXhhbXBsZS5jb20KVG86IGZha2V1c2VyQGV4YW1wbGUuY29tCkNjOgpCY2M6ClN1YmplY3Q6IEZyb20gTlN5bmMKTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSZxdW90O2lzby04ODU5LTEmcXVvdDsKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogN2JpdApYLU1pbWVPTEU6IFByb2R1Y2VkIEJ5IE1pY3Jvc29mdCBNaW1lT0xFIFY2LjAwLjI5MDAuMzM1MApUaGlzIGlzIHRoZSBib2R5IHRleHQuCg== + diff --git a/tests/activesync/activesync-031-sendmail-request.xml b/tests/activesync/activesync-031-sendmail-request.xml new file mode 100644 index 0000000..42d1dd9 --- /dev/null +++ b/tests/activesync/activesync-031-sendmail-request.xml @@ -0,0 +1,7 @@ + + + + 1 + + RnJvbTogPGphbmUuZG9lQGV4YW1wbGUuY29tPgpUbzogPGpvaG4uZG9lQGV4YW1wbGUuY29tPgpTdWJqZWN0OiBUZXN0IGVtYWlsIHN1YmplY3QKTUlNRS1WZXJzaW9uOiAxLjAKCnRlc3QgYm9keQo= + diff --git a/tests/activesync/activesync-032-formatted-base64.xml b/tests/activesync/activesync-032-formatted-base64.xml new file mode 100644 index 0000000..668d8fc --- /dev/null +++ b/tests/activesync/activesync-032-formatted-base64.xml @@ -0,0 +1,11 @@ + + + + 1 + + + RnJvbTogPGphbmUuZG9lQGV4YW1wbGUuY29tPgpUbzogPGpvaG4uZG9lQGV4YW1wbGU + uY29tPgpTdWJqZWN0OiBUZXN0IGVtYWlsIHN1YmplY3QKTUlNRS1WZXJzaW9uOiAxLj + AKCnRlc3QgYm9keQo= + + diff --git a/tests/airsync/airsync-001.xml b/tests/airsync/airsync-001.xml new file mode 100644 index 0000000..2a467c8 --- /dev/null +++ b/tests/airsync/airsync-001.xml @@ -0,0 +1,33 @@ + + + + + + Contacts + {F0A866C8-E590-42B9-830C-4CF4DFD545DF}12 + {F0A866C8-E590-42B9-830C-4CF4DFD545DF} + + + 100 + + 4 + 4 + 1 + + + + 2147483800 + + Bue, Tryggve + Tryggve + Bue + 12345678 + + + + + + + + diff --git a/tests/airsync/airsync-002-search_query_for_exchange.xml b/tests/airsync/airsync-002-search_query_for_exchange.xml new file mode 100644 index 0000000..1c9b379 --- /dev/null +++ b/tests/airsync/airsync-002-search_query_for_exchange.xml @@ -0,0 +1,22 @@ + + + + + Mailbox + + + Calendar + test + + + + + + 0-1 + + 2 + + + + diff --git a/tests/airsync/airsync-003-search_response_from_exchange.xml b/tests/airsync/airsync-003-search_response_from_exchange.xml new file mode 100644 index 0000000..2da32b4 --- /dev/null +++ b/tests/airsync/airsync-003-search_response_from_exchange.xml @@ -0,0 +1,102 @@ + + + + 1 + + + 1 + + Calendar + RgAAAADi22n%2b5K6eSoH%2bdzl9mrUlBwAiJdrFeosuS5FQPukoeMhpAH7xbHCsAAAiJdrFeosuS5FQPukoeMhpAH7zrksUAAAP + 3 + + iP///0YATABFACAAUwB0AGEAbgBkAGEAcgBkACAAVABpAG0AZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAFAAQAAAAAAAAAAAAAAEYATABFACAARABhAHkAbABpAGcAaAB0ACAAVABpAG0AZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAFAAMAAAAAAAAAxP///w== + 20090417T112208Z + 20090417T090000Z + hfjjf + 040000008200E00074C5B7101A82E00800000000F4BD10E469BEC901000000000000000010000000449579D4A72EED4EB3F70D04913F0277 + maemo + maemo@test.local + + + maemo@test.local + maemo + 0 + 1 + + + meetingroom testi + 20090417T100000Z + + 2 + 365 + <html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<meta name="Generator" content="Microsoft Exchange Server"> +<!-- converted from text --> +<style>.EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; }</style></head> +<body> +<font size="2"><div class="PlainText">&nbsp;</div></font> +</body> +</html> + + 0 + 0 + 0 + 15 + 5 + 1 + + + + Calendar + RgAAAADi22n%2b5K6eSoH%2bdzl9mrUlBwAiJdrFeosuS5FQPukoeMhpAH7xbHCsAAAiJdrFeosuS5FQPukoeMhpAH7zrksSAAAP + 3 + + iP///0YATABFACAAUwB0AGEAbgBkAGEAcgBkACAAVABpAG0AZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAFAAQAAAAAAAAAAAAAAEYATABFACAARABhAHkAbABpAGcAaAB0ACAAVABpAG0AZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAFAAMAAAAAAAAAxP///w== + 20090417T105620Z + 20090417T110000Z + tent + 040000008200E00074C5B7101A82E008000000002E1A5BA069BEC901000000000000000010000000F1BB45467D72B44F822E9686F1D18ED4 + maemo + maemo@test.local + + + meetingroomtest@test.local + meetingroom testi + 0 + 3 + + + maemo@test.local + maemo + 0 + 1 + + + meetingroom testi + 20090417T120000Z + + 2 + 365 + <html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<meta name="Generator" content="Microsoft Exchange Server"> +<!-- converted from text --> +<style>.EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; }</style></head> +<body> +<font size="2"><div class="PlainText">&nbsp;</div></font> +</body> +</html> + + 0 + 0 + 0 + 15 + 5 + 1 + + + 0-1 + 19 + + + diff --git a/tests/airsync/airsync-004-binary_byte_array.xml b/tests/airsync/airsync-004-binary_byte_array.xml new file mode 100644 index 0000000..4ced458 --- /dev/null +++ b/tests/airsync/airsync-004-binary_byte_array.xml @@ -0,0 +1,43 @@ + + + + + + 16668481 + 14 + 1 + + + 14:4 + + "Moti" <moti@example.com> + "Momo" <momo@example.org> + Hello world! + "Momo" <momo@example.org> + 2010-12-28T22:30:09.906Z + Moti + Hello world! + 1 + 1 + + 2 + 8224 + 1 + Bla bla bla + Guten tag + + IPM.Note + 28591 + + urn:content-classes:message + 2 + + bdpgj2qneuaae+o81xg/bQ== + ACUM3SI= + + + + + + + diff --git a/tests/conml/conml-001.xml b/tests/conml/conml-001.xml new file mode 100644 index 0000000..b446698 --- /dev/null +++ b/tests/conml/conml-001.xml @@ -0,0 +1,16 @@ + + + + + + + + C:\Temp\MyApp + + + + + + diff --git a/tests/conml/conml-002.xml b/tests/conml/conml-002.xml new file mode 100644 index 0000000..2418a3e --- /dev/null +++ b/tests/conml/conml-002.xml @@ -0,0 +1,11 @@ + + + + + + + C:\Data\Installs\helloworldbasic.sis + + + + diff --git a/tests/ddf/ddf-001.ddf b/tests/ddf/ddf-001.ddf new file mode 100644 index 0000000..17c6000 --- /dev/null +++ b/tests/ddf/ddf-001.ddf @@ -0,0 +1,55 @@ + + + + 1.2 + + E-Mail + + + + + + com.operatorX.dm/1.0/EMail + + + + POP3 + + POPServer + + + + + + text/plain + + + mail.Operatorx.com + + + UserID + + + + + + text/plain + + + UserName + + + PWD + + + + + + text/plain + + + 4571F7C34A9876B3 + + + + diff --git a/tests/ddf/syncml_with_ddf-001.xml b/tests/ddf/syncml_with_ddf-001.xml new file mode 100644 index 0000000..edfddf5 --- /dev/null +++ b/tests/ddf/syncml_with_ddf-001.xml @@ -0,0 +1,153 @@ + + + + + 1.2 + SyncML/1.2 + 1 + 2 + + IMEI:493005100592800 + + + http://www.syncml.org/sync-server + + + + + 1 + 2 + 0 + SyncHdr + http://www.syncml.org/sync-server + IMEI:493005100592800 + 200 + + + + 2 + 2 + 3 + Sync + ./contacts/james_bond + ./dev-contacts + 200 + + + + 3 + 2 + 4 + Replace + 1012 + 200 + + + + 4 + + ./dev-contacts + + + ./contacts/james_bond + + + 5 + + text/x-vcard + + + + 1023 + + + + + + + 6 + + text/x-vcard + + + + 10536681 + + + + + + + + 4 + + + /OperatorX + + + xml + + application/vnd.syncml.dmtnds+xml + + + + + 1.2 + + E-Mail + + + + + + com.operatorX.dm/1.0/EMail + + + + POP3 + + POPServer + + + + + + text/plain + + + mail.Operatorx.com + + + UserID + + + + + + text/plain + + + UserName + + + PWD + + + + + + text/plain + + + 4571F7C34A9876B3 + + + + + + + + + + + diff --git a/tests/drmrel/drmrel-001.xml b/tests/drmrel/drmrel-001.xml new file mode 100644 index 0000000..4a85ab2 --- /dev/null +++ b/tests/drmrel/drmrel-001.xml @@ -0,0 +1,17 @@ + + + + + 1.0 + + + + + cid:4567829547@foo.com + + + + + + + diff --git a/tests/drmrel/drmrel-002.xml b/tests/drmrel/drmrel-002.xml new file mode 100644 index 0000000..a9cb91b --- /dev/null +++ b/tests/drmrel/drmrel-002.xml @@ -0,0 +1,20 @@ + + + + + 1.0 + + + + + cid:4567829547@foo.com + + + Cei4QxjWo9Kg8D3pKgxw= + + + + + + + \ No newline at end of file diff --git a/tests/drmrel/drmrel-003.xml b/tests/drmrel/drmrel-003.xml new file mode 100644 index 0000000..601ca1a --- /dev/null +++ b/tests/drmrel/drmrel-003.xml @@ -0,0 +1,24 @@ + + + + + 1.0 + + + + + cid:4567829547@foo.com + + + Cei4QxjWo9Kg8D3pKgxw= + + + + + + 1 + + + + + diff --git a/tests/emn/emn-001.xml b/tests/emn/emn-001.xml new file mode 100644 index 0000000..0935fab --- /dev/null +++ b/tests/emn/emn-001.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-002.xml b/tests/emn/emn-002.xml new file mode 100644 index 0000000..d259a4c --- /dev/null +++ b/tests/emn/emn-002.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-003.xml b/tests/emn/emn-003.xml new file mode 100644 index 0000000..076666d --- /dev/null +++ b/tests/emn/emn-003.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-004.xml b/tests/emn/emn-004.xml new file mode 100644 index 0000000..09a258f --- /dev/null +++ b/tests/emn/emn-004.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-005.xml b/tests/emn/emn-005.xml new file mode 100644 index 0000000..251fef4 --- /dev/null +++ b/tests/emn/emn-005.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-006.xml b/tests/emn/emn-006.xml new file mode 100644 index 0000000..8b1540f --- /dev/null +++ b/tests/emn/emn-006.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-007.xml b/tests/emn/emn-007.xml new file mode 100644 index 0000000..faceff6 --- /dev/null +++ b/tests/emn/emn-007.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-008.xml b/tests/emn/emn-008.xml new file mode 100644 index 0000000..8eabc96 --- /dev/null +++ b/tests/emn/emn-008.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-009.xml b/tests/emn/emn-009.xml new file mode 100644 index 0000000..f424e8f --- /dev/null +++ b/tests/emn/emn-009.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-010.xml b/tests/emn/emn-010.xml new file mode 100644 index 0000000..d366581 --- /dev/null +++ b/tests/emn/emn-010.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-011.xml b/tests/emn/emn-011.xml new file mode 100644 index 0000000..0661d65 --- /dev/null +++ b/tests/emn/emn-011.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-012.xml b/tests/emn/emn-012.xml new file mode 100644 index 0000000..446f306 --- /dev/null +++ b/tests/emn/emn-012.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-013.xml b/tests/emn/emn-013.xml new file mode 100644 index 0000000..fe00e0b --- /dev/null +++ b/tests/emn/emn-013.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-014.xml b/tests/emn/emn-014.xml new file mode 100644 index 0000000..0935fab --- /dev/null +++ b/tests/emn/emn-014.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-015.xml b/tests/emn/emn-015.xml new file mode 100644 index 0000000..1108921 --- /dev/null +++ b/tests/emn/emn-015.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-016.xml b/tests/emn/emn-016.xml new file mode 100644 index 0000000..be86be1 --- /dev/null +++ b/tests/emn/emn-016.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/emn/emn-017.xml b/tests/emn/emn-017.xml new file mode 100644 index 0000000..07c582f --- /dev/null +++ b/tests/emn/emn-017.xml @@ -0,0 +1,4 @@ + + + + diff --git a/tests/launchTests.sh b/tests/launchTests.sh new file mode 100755 index 0000000..e41a749 --- /dev/null +++ b/tests/launchTests.sh @@ -0,0 +1,206 @@ +#!/bin/sh + +# Copyright (C) 2009 Michael Bell + +# setup correct path for binaries if they are not in $PATH +if [ "${CMAKE_CURRENT_BINARY_DIR}" ] +then + WBXML2XML="${CMAKE_CURRENT_BINARY_DIR}/tools/wbxml2xml" + XML2WBXML="${CMAKE_CURRENT_BINARY_DIR}/tools/xml2wbxml" +else + WBXML2XML=`which wbxml2xml` + XML2WBXML=`which xml2wbxml` +fi + +if [ " ${PERL_PROGRAM}" != " " ] +then + PERL_BIN="${PERL_PROGRAM}" +else + PERL_BIN=`which perl` +fi + +NORMALIZE_SCRIPT="${CMAKE_CURRENT_BINARY_DIR}/normalize_xml.pl" + +if [ " ${DIFF_PROGRAM}" != " " ] +then + DIFF_BIN="${DIFF_PROGRAM}" +else + DIFF_BIN=`which diff` +fi + +if [ ! -x "$WBXML2XML" ] +then + echo Set WBXML2XML to the binary executable of wbxml2xml tool in order to use that script. + exit 1 +fi + +if [ ! -x "$XML2WBXML" ] +then + echo Set XML2XWBML to the binary executable of xml2wbxml tool in order to use that script. + exit 1 +fi + +# if somebody enabled CMAKE_SKIP_RPATH +# then it is necessary to specify the path to the library +# Debian does this by default +if [ "${CMAKE_SKIP_RPATH}" ] +then + LD_LIBRARY_PATH="${CMAKE_CURRENT_BINARY_DIR}/src" + export LD_LIBRARY_PATH +fi + +# Go to test suite directory +if [ " $1" != " " -a -d "$1" ] +then + TEST_SUITE_DIR="$1" +else + TEST_SUITE_DIR=`dirname $0` +fi + +cd "$TEST_SUITE_DIR" || exit 1 +PWD=`pwd` + +echo Test suite directory is $PWD + +# Create temporary directory +TMP_DIR=`mktemp -d -t LibWBXMLTestSuite.XXX` + +# execute only a special test directory +if [ " $2" != " " ] +then + DIRLIST=`find $PWD/. \( -type d -a -name $2 -a ! -name . -prune \) -print | sort` + if [ ! "$DIRLIST" ] + then + DIRLIST=`find $PWD/. \( -type d -a ! -name "*svn*" -a ! -name . -prune \) -print | sort` + COUNTER=0 + for ITEM in $DIRLIST + do + if [ "$COUNTER" -eq "$2" ] + then + RESULT=$ITEM + fi + COUNTER=`expr $COUNTER + 1` + done + DIRLIST=$RESULT + fi +else + DIRLIST=`find $PWD/. \( -type d -a ! -name "*svn*" -a ! -name . -prune \) -print | sort` +fi + +# For each directory +RESULT="SUCCEEDED" +for i in $DIRLIST +do + if [ $i != `pwd` ]; then + + echo ---------------------------- + echo Entering into: `basename $i` + echo ---------------------------- + + # execute only a special test in a directory + if [ `basename $i` != 'ddf' ]; then + TESTLIST=`find $i/. \( -type f -name "*.xml" -a ! -name . -prune \) -print | sort` + else + TESTLIST=`find $i/. \( -type f \( -name "*.ddf" -or -name "*.xml" \) -a ! -name . -prune \) -print | sort` + fi + if [ " $3" != " " ] + then + COUNTER=0 + for ITEM in $TESTLIST + do + COUNTER=`expr $COUNTER + 1` + if [ "$COUNTER" -eq "$3" ] + then + TESTCASE=$ITEM + fi + done + TESTLIST=$TESTCASE + fi + + # For each directory + for j in $TESTLIST + do + echo . `basename $j` + + OUT_WBXML="$TMP_DIR/`basename $i`/`basename $j .xml`.wbxml" + OUT_XML="$TMP_DIR/`basename $i`/`basename $j`" + + # Create output directory if they don't exist + if [ ! -d "$TMP_DIR/`basename $i`" ]; then + mkdir -p "$TMP_DIR/`basename $i`" + fi + + # XML ==> WBXML + echo Converting into: $OUT_WBXML + if [ "$TESTDIR" != "ota" -a "$TESTDIR" != "airsync" ]; then + # disable string tables if they are not really necessary + NO_STR_TBL="-n"; + fi + CMD="$XML2WBXML $NO_STR_TBL -o $OUT_WBXML $j" + $CMD + if [ $? != 0 ]; then RESULT="FAILED"; fi + + # WBXML ==> XML + echo Converting back: $OUT_XML + TESTDIR=`basename $i` + if [ "$TESTDIR" = "ota" ]; + then + PARAMS="-l OTA" + else if [ "$TESTDIR" = "airsync" ]; + then + PARAMS="-l AIRSYNC" + else if [ "$TESTDIR" = "ddf" -a `basename $j` != `basename $j ddf` ]; + then + # only pure DDF documents need this option + # embedded DDF documents do not need this option + PARAMS="-l DMDDF12" + else + PARAMS="" + fi fi fi + CMD="$WBXML2XML $PARAMS -o $OUT_XML $OUT_WBXML" + $CMD + if [ $? != 0 ]; then RESULT="FAILED"; fi + + # compare original and generated XML + echo -n "Comparing the original and the generated XML ... " + if [ " $PERL_BIN" = " " -o " $DIFF_BIN" = " " ] + then + echo UNSUPPORTED + else if [ `basename $j` = "syncml-012.xml" -o `basename $j` = "syncml-013.xml" -o `basename $j` = "activesync-032-formatted-base64.xml" ] + then + # SyncML CDATA fix makes comparing sometimes impossible + echo CDATA_ENCAPSULATION + else + $PERL_BIN $NORMALIZE_SCRIPT --delete-attribute xmlns $j $OUT_XML.org + $PERL_BIN $NORMALIZE_SCRIPT --delete-attribute xmlns $OUT_XML $OUT_XML.new + DIFF_RESULT=`$DIFF_BIN -b $OUT_XML.org $OUT_XML.new` + if [ " $DIFF_RESULT" != " " ]; + then + echo FAILED + RESULT="FAILED"; + else + echo SUCCEEDED + fi + fi fi + done + + fi +done + +# Cleanup +if [ "$RESULT" == "SUCCEEDED" ]; +then + rm -rf "$TMP_DIR"; +fi + +echo --------------------------- +echo \\o/ Finished ! Yeah ! \\o/ +echo --------------------------- + +echo $RESULT +if [ "$RESULT" != "SUCCEEDED" ]; +then + exit 1; +else + exit 0; +fi diff --git a/tests/normalize_xml.pl b/tests/normalize_xml.pl new file mode 100644 index 0000000..53a5260 --- /dev/null +++ b/tests/normalize_xml.pl @@ -0,0 +1,392 @@ +#!@PERL_PROGRAM@ + +# Copyright (C) 2009 Michael Bell + +use strict; +use warnings FATAL => qw( all ); +use English; + +# check params +# 1. original file +# 2. new file +# 3. no more params + +my $ignore_attribute = ""; +if ($ARGV[0] eq "--delete-attribute") { + shift; + die "The attribute which must be deleted is missing." + if (not $ARGV[0]); + $ignore_attribute = shift; +} + +die "There must be two arguments (old and new file)." + if (scalar(@ARGV) != 2); + +my $org_filename = $ARGV[0]; +my $new_filename = $ARGV[1]; + +die "The original file does not exist." + if (not $org_filename or not -e $org_filename); + +die "The new file is not valid filename." + if (not $new_filename); + +die "The new file exists already." + if (-e $new_filename); + +# open files + +die "The original file is not readable." + if (not open(my $ORG_FD, "<", $org_filename)); + +die "The new file is not writeable." + if (not open(my $NEW_FD, ">", $new_filename)); + +# look for the XML tree +# - version and encoding +# - DTD +# - XML tree + +my $line = <$ORG_FD>; + +my $state = "IGNORE"; +do { + ## determine state + + ## XML detection + if ($state eq "IGNORE" and $line =~ q{^\s*<[a-zA-Z]}) { + $state = "XML_TREE"; + } + + ## version and encoding detection + if ($state eq "IGNORE" and $line =~ q{^\s*<\?}) { + $state = "ENC_OPEN"; + } + if ($state eq "ENC_OPEN" and $line =~ q{^\s*<\?.*\?>\s*$} and $line !~ q{\sencoding="[^"]*"}) { + # add default encoding + $line =~ s{\s*\?>\s*$}{ encoding="UTF-8"?>\n}; + } + if ($state eq "ENC_OPEN" and $line =~ q{\?>\s*$}) { + ## uppercase encoding + my $encoding = $line; + $encoding =~ s{.*\sencoding="([^"]*)".*}{$1}; + $encoding = uc($encoding); + $line =~ s{\sencoding="[^"]*"}{ encoding="${encoding}"}; + $state = "WRITE"; + } + + ## DTD detection + if ($state eq "IGNORE" and $line =~ q{^\s*\]}) { + ## such special XML stuff is lost in WBXML + $line =~ s{\s\[<\?.*\?>\]}{}; + } + if ($state eq "DTD_OPEN" and $line =~ q{>\s*$}) { + $state = "WRITE"; + } + + ## comment detection + if ($state eq "IGNORE" and $line =~ q{^\s*\s*$}) { + $state = "IGNORE"; + } + + ## handle data + if ($state eq "IGNORE") { + $line = <$ORG_FD>; + } + if ($state eq "WRITE") { + $line =~ s{[\s\r\n]*$}{\n}s; + print $NEW_FD $line; + $line = <$ORG_FD>; + $state = "IGNORE"; + } + if ($state =~ q{_OPEN$}) { + $line .= <$ORG_FD>; + $line =~ s{\s*[\n\r]+\s*}{ }sg; + $line .= "\n"; + } +} while ($state ne "XML_TREE"); + +# XML tree state +# - element +# < +# element name +# blank +# attribute name +# = attribute assignment +# attribute value +# > +# - data +# - comment + +my $indent = 0; +my $char = ""; +my $text = ""; +my $element = ""; +my $expected = ""; +$state = "NEUTRAL"; +while (1) { + ## $line works line oriented + ## but the parser works character oriented + last if (not defined $line); + if (length ($line) == 0) { + $line = <$ORG_FD>; + last if (not defined $line or length($line) < 1); + } + $char = substr($line, 0, 1); + $line = substr($line, 1); + + # check state + + # reset text state + if ($state eq "TEXT_NEWLINE" and $char !~ q{[\s\n\r]}) { + $state = "NEUTRAL"; + } + + # ignore leading blanks (normalization) + if ($state eq "NEUTRAL" and $char =~ q{\s}) { + next; + } + + # handle comment or element which starts in a text line + if ($state eq "TEXT" and $char eq "<") { + if (length($expected)) { + # the original text must be replaced for test validation + $text = $expected; + $expected = ""; + } + $text =~ s{\s*$}{}; + print $NEW_FD "${text}\n"; + $state = "NEUTRAL"; + } + + # try to handle a new comment or element + if ($state eq "NEUTRAL" and $char eq "<") { + # let's look forward (element or comment) + die "A standalone smaller than "<" sign is not allowed in XML." + if (length($line) < 1); + $char = substr($line, 0, 1); + $line = substr($line, 1); + if ($char eq "!") { + if ($line =~ q{^--}) { + ## this should be a comment + $char = substr($line, 0, 2); + $line = substr($line, 2); + $state = "COMMENT"; + $text = ""; + } elsif ($line =~ q{^\[CDATA\[}) { + ## CDATA section detected + for (my $i = 0; $i < $indent; $i++) { + print $NEW_FD " "; + } + print $NEW_FD "") { + # end of comment + $line = substr($line, 2); + $state = "NEUTRAL"; + # check if this is a special action configuration + if ($text =~ m{^\sEXPECTED\s::=\s.*\s$}) { + # This is the value for the next text data. + $expected = $text; + $expected =~ s{^\sEXPECTED\s::=\s(.*)\s$}{$1}; + $text = ""; + } + } else { + $text .= $char; + } + next; + } + + # read and write text data + if ($state eq "NEUTRAL" and $char ne "<") { + # new text data + for (my $i = 0; $i < $indent; $i++) { + print $NEW_FD " "; + } + $text = $char; + $state = "TEXT"; + next; + } + if ($state eq "TEXT" and $char eq "\r") { + next; + } + if ($state eq "TEXT" and $char eq "\n") { + $text =~ s{\s*$}{}; + print $NEW_FD "${text}\n"; + $state = "TEXT_NEWLINE"; + next; + } + # if & is not handled as & then this error cannot be recovered + if ($state eq "TEXT" and $char eq '"') { + $text .= """; + next; + } + if ($state eq "TEXT" and $char eq "'") { + $text .= "'"; + next; + } + if ($state eq "TEXT" and $char eq '<') { + $text .= "<"; + next; + } + if ($state eq "TEXT" and $char eq '>') { + $text .= ">"; + next; + } + if ($state eq "TEXT") { + $text .= $char; + next; + } + if ($state eq "TEXT_NEWLINE" and $char =~ q{\s\r\n}) { + next; + } + + # read element name + if ($state eq "ELEMENT" and $char =~ q{[a-zA-Z0-9_]}) { + print $NEW_FD $char; + $element .= $char; + next; + } + + # detect space for potential attribute + if ($state eq "ELEMENT" and $char =~ q{[\s\r\n]}) { + $state = "POTENTIAL_ATTRIBUTE"; + next; + } + + # detect and read attribute + if ($state eq "POTENTIAL_ATTRIBUTE" and $char =~ q{[a-zA-Z0-9_]}) { + if ($ignore_attribute and + substr($ignore_attribute, 0, 1) eq $char and + substr($ignore_attribute, 1) eq substr($line, 0, length(substr($ignore_attribute, 1)))) + { + # let's ingore the attribute + $line =~ s{^[a-zA-Z_1-9]*=}{}; + if (substr($line, 0, 1) eq "'") { + $line =~ s{^'[^']*'}{}; + } else { + $line =~ s{^"[^"]*"}{}; + } + next; + } + $state = "ATTRIBUTE_NAME"; + print $NEW_FD " "; + } + if ($state eq "ATTRIBUTE_NAME" and $char =~ q{[a-zA-Z0-9_]}) { + print $NEW_FD $char; + next; + } + if ($state eq "ATTRIBUTE_NAME" and $char eq "=") { + print $NEW_FD $char; + $state = "ATTRIBUTE_ASSIGN"; + next; + } + if ($state eq "ATTRIBUTE_ASSIGN" and $char eq '"') { + print $NEW_FD $char; + $state = "ATTRIBUTE_VALUE_QUOT"; + next; + } + if ($state eq "ATTRIBUTE_VALUE_QUOT" and $char ne '"') { + print $NEW_FD $char; + next; + } + if ($state eq "ATTRIBUTE_VALUE_QUOT" and $char eq '"') { + print $NEW_FD $char; + $state = "POTENTIAL_ATTRIBUTE"; + next; + } + if ($state eq "ATTRIBUTE_ASSIGN" and $char eq "'") { + print $NEW_FD $char; + $state = "ATTRIBUTE_VALUE_APOS"; + next; + } + if ($state eq "ATTRIBUTE_VALUE_APOS" and $char ne "'") { + print $NEW_FD $char; + next; + } + if ($state eq "ATTRIBUTE_VALUE_APOS" and $char eq "'") { + print $NEW_FD $char; + $state = "POTENTIAL_ATTRIBUTE"; + next; + } + + # handle standalone element + if (($state eq "ELEMENT" or $state eq "POTENTIAL_ATTRIBUTE") + and $char eq "/") + { + # consume the closing ">" and add the complete closing tag + $char = ">"; + $line =~ s{^\s*>}{}; + $indent--; + print $NEW_FD ">\n"; + for (my $i = 0; $i < $indent; $i++) { + print $NEW_FD " "; + } + print $NEW_FD "\n"; + $state = "NEUTRAL"; + next; + } + + # read element end + if (($state eq "ELEMENT" or $state eq "POTENTIAL_ATTRIBUTE") + and $char eq ">") + { + print $NEW_FD $char."\n"; + $state = "NEUTRAL"; + next; + } + + # handle CDATA + if ($state eq "CDATA" and $char eq "]" and substr($line , 0, 2) eq "]>") { + $line = substr($line, 2); + print $NEW_FD "]]>\n"; + $state = "NEUTRAL"; + next; + } + if ($state eq "CDATA") { + print $NEW_FD $char; + next; + } +}; + +# close files + +close $ORG_FD; +close $NEW_FD; diff --git a/tests/ota/ota-001.xml b/tests/ota/ota-001.xml new file mode 100644 index 0000000..bde32cb --- /dev/null +++ b/tests/ota/ota-001.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/ota/ota-002.xml b/tests/ota/ota-002.xml new file mode 100644 index 0000000..896fd45 --- /dev/null +++ b/tests/ota/ota-002.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/ota/ota-003.xml b/tests/ota/ota-003.xml new file mode 100644 index 0000000..508d56f --- /dev/null +++ b/tests/ota/ota-003.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/tests/prov/prov-001.xml b/tests/prov/prov-001.xml new file mode 100644 index 0000000..bf4fbc2 --- /dev/null +++ b/tests/prov/prov-001.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/prov/prov-002.xml b/tests/prov/prov-002.xml new file mode 100644 index 0000000..611c179 --- /dev/null +++ b/tests/prov/prov-002.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/prov/prov-003.xml b/tests/prov/prov-003.xml new file mode 100644 index 0000000..b8b96ac --- /dev/null +++ b/tests/prov/prov-003.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/prov/prov-004.xml b/tests/prov/prov-004.xml new file mode 100644 index 0000000..fb72f9b --- /dev/null +++ b/tests/prov/prov-004.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/prov/prov-005.xml b/tests/prov/prov-005.xml new file mode 100644 index 0000000..a86fbd5 --- /dev/null +++ b/tests/prov/prov-005.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + diff --git a/tests/prov/prov-006.xml b/tests/prov/prov-006.xml new file mode 100644 index 0000000..b738ce1 --- /dev/null +++ b/tests/prov/prov-006.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/prov/prov-007.xml b/tests/prov/prov-007.xml new file mode 100644 index 0000000..bb1d4b9 --- /dev/null +++ b/tests/prov/prov-007.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/prov/prov-008.xml b/tests/prov/prov-008.xml new file mode 100644 index 0000000..3973fea --- /dev/null +++ b/tests/prov/prov-008.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/si/si-001.xml b/tests/si/si-001.xml new file mode 100644 index 0000000..f081b81 --- /dev/null +++ b/tests/si/si-001.xml @@ -0,0 +1,10 @@ + + + + + You have 4 new emails + + \ No newline at end of file diff --git a/tests/si/si-002.xml b/tests/si/si-002.xml new file mode 100644 index 0000000..3599463 --- /dev/null +++ b/tests/si/si-002.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/tests/si/si-003.xml b/tests/si/si-003.xml new file mode 100644 index 0000000..c059f23 --- /dev/null +++ b/tests/si/si-003.xml @@ -0,0 +1,16 @@ + + + + + Can you feel it ? + + + + + + \ No newline at end of file diff --git a/tests/si/si-004.xml b/tests/si/si-004.xml new file mode 100644 index 0000000..eea92a3 --- /dev/null +++ b/tests/si/si-004.xml @@ -0,0 +1,8 @@ + + + + + si-004 + + \ No newline at end of file diff --git a/tests/si/si-005.xml b/tests/si/si-005.xml new file mode 100644 index 0000000..5e8972c --- /dev/null +++ b/tests/si/si-005.xml @@ -0,0 +1,8 @@ + + + + + si-005 + + \ No newline at end of file diff --git a/tests/si/si-006.xml b/tests/si/si-006.xml new file mode 100644 index 0000000..a1c31a2 --- /dev/null +++ b/tests/si/si-006.xml @@ -0,0 +1,8 @@ + + + + + si-006 + + \ No newline at end of file diff --git a/tests/si/si-007.xml b/tests/si/si-007.xml new file mode 100644 index 0000000..f17b2d7 --- /dev/null +++ b/tests/si/si-007.xml @@ -0,0 +1,8 @@ + + + + + si-007 + + \ No newline at end of file diff --git a/tests/si/si-008.xml b/tests/si/si-008.xml new file mode 100644 index 0000000..c22f1e1 --- /dev/null +++ b/tests/si/si-008.xml @@ -0,0 +1,8 @@ + + + + + si-008 + + \ No newline at end of file diff --git a/tests/si/si-009.xml b/tests/si/si-009.xml new file mode 100644 index 0000000..1c4ea88 --- /dev/null +++ b/tests/si/si-009.xml @@ -0,0 +1,8 @@ + + + + + si-009 + + \ No newline at end of file diff --git a/tests/si/si-010.xml b/tests/si/si-010.xml new file mode 100644 index 0000000..3bdca6a --- /dev/null +++ b/tests/si/si-010.xml @@ -0,0 +1,8 @@ + + + + + si-010 + + \ No newline at end of file diff --git a/tests/si/si-011.xml b/tests/si/si-011.xml new file mode 100644 index 0000000..70c9e09 --- /dev/null +++ b/tests/si/si-011.xml @@ -0,0 +1,8 @@ + + + + + si-011 + + \ No newline at end of file diff --git a/tests/si/si-012.xml b/tests/si/si-012.xml new file mode 100644 index 0000000..b898f41 --- /dev/null +++ b/tests/si/si-012.xml @@ -0,0 +1,8 @@ + + + + + si-012 + + \ No newline at end of file diff --git a/tests/si/si-013.xml b/tests/si/si-013.xml new file mode 100644 index 0000000..ecb164c --- /dev/null +++ b/tests/si/si-013.xml @@ -0,0 +1,8 @@ + + + + + si-013 + + \ No newline at end of file diff --git a/tests/si/si-014.xml b/tests/si/si-014.xml new file mode 100644 index 0000000..8ffa55d --- /dev/null +++ b/tests/si/si-014.xml @@ -0,0 +1,8 @@ + + + + + si-014 + + \ No newline at end of file diff --git a/tests/si/si-015.xml b/tests/si/si-015.xml new file mode 100644 index 0000000..339f320 --- /dev/null +++ b/tests/si/si-015.xml @@ -0,0 +1,8 @@ + + + + + si-015 + + \ No newline at end of file diff --git a/tests/si/si-016.xml b/tests/si/si-016.xml new file mode 100644 index 0000000..28f76a3 --- /dev/null +++ b/tests/si/si-016.xml @@ -0,0 +1,8 @@ + + + + + si-016 + + \ No newline at end of file diff --git a/tests/si/si-017.xml b/tests/si/si-017.xml new file mode 100644 index 0000000..b474e58 --- /dev/null +++ b/tests/si/si-017.xml @@ -0,0 +1,8 @@ + + + + + si-017 + + \ No newline at end of file diff --git a/tests/si/si-018.xml b/tests/si/si-018.xml new file mode 100644 index 0000000..aded6ef --- /dev/null +++ b/tests/si/si-018.xml @@ -0,0 +1,8 @@ + + + + + si-018 + + \ No newline at end of file diff --git a/tests/si/si-019.xml b/tests/si/si-019.xml new file mode 100644 index 0000000..5175e9b --- /dev/null +++ b/tests/si/si-019.xml @@ -0,0 +1,8 @@ + + + + + si-019 + + \ No newline at end of file diff --git a/tests/si/si-020.xml b/tests/si/si-020.xml new file mode 100644 index 0000000..6e28607 --- /dev/null +++ b/tests/si/si-020.xml @@ -0,0 +1,11 @@ + + + + + si-020 + + + + + \ No newline at end of file diff --git a/tests/si/si-021.xml b/tests/si/si-021.xml new file mode 100644 index 0000000..5639145 --- /dev/null +++ b/tests/si/si-021.xml @@ -0,0 +1,13 @@ + + + + + si-021 + + + + + + + \ No newline at end of file diff --git a/tests/si/si-022.xml b/tests/si/si-022.xml new file mode 100644 index 0000000..f9ed6be --- /dev/null +++ b/tests/si/si-022.xml @@ -0,0 +1,8 @@ + + + + + si-022 + + \ No newline at end of file diff --git a/tests/si/si-023.xml b/tests/si/si-023.xml new file mode 100644 index 0000000..3b109e9 --- /dev/null +++ b/tests/si/si-023.xml @@ -0,0 +1,8 @@ + + + + + si-023 + + \ No newline at end of file diff --git a/tests/si/si-024.xml b/tests/si/si-024.xml new file mode 100644 index 0000000..32aebf4 --- /dev/null +++ b/tests/si/si-024.xml @@ -0,0 +1,8 @@ + + + + + si-024 + + \ No newline at end of file diff --git a/tests/si/si-025.xml b/tests/si/si-025.xml new file mode 100644 index 0000000..125f279 --- /dev/null +++ b/tests/si/si-025.xml @@ -0,0 +1,8 @@ + + + + + si-025 + + \ No newline at end of file diff --git a/tests/sl/sl-001.xml b/tests/sl/sl-001.xml new file mode 100644 index 0000000..1e28d95 --- /dev/null +++ b/tests/sl/sl-001.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-002.xml b/tests/sl/sl-002.xml new file mode 100644 index 0000000..123e09e --- /dev/null +++ b/tests/sl/sl-002.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-003.xml b/tests/sl/sl-003.xml new file mode 100644 index 0000000..33b3760 --- /dev/null +++ b/tests/sl/sl-003.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-004.xml b/tests/sl/sl-004.xml new file mode 100644 index 0000000..3fa8886 --- /dev/null +++ b/tests/sl/sl-004.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-005.xml b/tests/sl/sl-005.xml new file mode 100644 index 0000000..fd51a7f --- /dev/null +++ b/tests/sl/sl-005.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-006.xml b/tests/sl/sl-006.xml new file mode 100644 index 0000000..d5dc2c3 --- /dev/null +++ b/tests/sl/sl-006.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-007.xml b/tests/sl/sl-007.xml new file mode 100644 index 0000000..29b0572 --- /dev/null +++ b/tests/sl/sl-007.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-008.xml b/tests/sl/sl-008.xml new file mode 100644 index 0000000..a35e10c --- /dev/null +++ b/tests/sl/sl-008.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-009.xml b/tests/sl/sl-009.xml new file mode 100644 index 0000000..5715472 --- /dev/null +++ b/tests/sl/sl-009.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-010.xml b/tests/sl/sl-010.xml new file mode 100644 index 0000000..828a66f --- /dev/null +++ b/tests/sl/sl-010.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-011.xml b/tests/sl/sl-011.xml new file mode 100644 index 0000000..c88082a --- /dev/null +++ b/tests/sl/sl-011.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-012.xml b/tests/sl/sl-012.xml new file mode 100644 index 0000000..142a4b0 --- /dev/null +++ b/tests/sl/sl-012.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/sl/sl-013.xml b/tests/sl/sl-013.xml new file mode 100644 index 0000000..8870b54 --- /dev/null +++ b/tests/sl/sl-013.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/syncml/syncml-001.xml b/tests/syncml/syncml-001.xml new file mode 100644 index 0000000..7d674fe --- /dev/null +++ b/tests/syncml/syncml-001.xml @@ -0,0 +1,21 @@ + + + + + 1.1 + SyncML/1.1 + 1 + 2 + IMEI:493005100592800 + http://www.syncml.org/sync-server + + + + 1 + 20SyncHdr + http://www.syncml.org/sync-server + IMEI:493005100592800 + 101 + + + diff --git a/tests/syncml/syncml-002.xml b/tests/syncml/syncml-002.xml new file mode 100644 index 0000000..4f2d909 --- /dev/null +++ b/tests/syncml/syncml-002.xml @@ -0,0 +1,22 @@ + + + + + 1.1 + SyncML/1.1 + 1 + 3 + http://www.syncml.org/sync-server + IMEI:493005100592800 + + + + 1 + 221 + + http://www.syncml.org/sync-server + IMEI:493005100592800 + + + + diff --git a/tests/syncml/syncml-003.xml b/tests/syncml/syncml-003.xml new file mode 100644 index 0000000..1dd1100 --- /dev/null +++ b/tests/syncml/syncml-003.xml @@ -0,0 +1,92 @@ + + + + + 1.1 + SyncML/1.1 + 1 + 1 + http://www.syncml.org/sync-server + IMEI:493005100592800 + + syncml:auth-basic + QnJ1Y2UyOk9oQmVoYXZl + + + 5000 + + + + + 1 + 200 + + ./contacts/james_bond + ./dev-contacts + + + 234 + 276 + + + + + + 2 + application/vnd.syncml-devinf+xml + + ./devinf11 + + + Big Factory, Ltd. + 4119 + Jane's phones + 2.0e + 2.0 + 1.22I + 1218182THD000001-2 + phone + + ./contacts + Phonebook + 32 + + text/x-vcard + 2.1 + + + text/x-vcard + 2.1 + + + + text/x-vcard + BEGIN + VCARD + END + VCARD + VERSION + 2.1 + N + TEL + VOICE + CELL + + + 01 + 02 + + + + + + + 3 + application/vnd.syncml-devinf+xml + + ./devinf11 + + + + + diff --git a/tests/syncml/syncml-004.xml b/tests/syncml/syncml-004.xml new file mode 100644 index 0000000..33edd95 --- /dev/null +++ b/tests/syncml/syncml-004.xml @@ -0,0 +1,123 @@ + + + + + 1.1 + SyncML/1.1 + 1 + 1 + IMEI:493005100592800 + http://www.syncml.org/sync-server + + syncml:auth-basic + QnJ1Y2UyOk9oQmVoYXZl + + + + + 1 + 10SyncHdr + http://www.syncml.org/sync-server + IMEI:493005100592800 + 212 + + + 2 + 11Alert + ./contacts/james_bond + ./dev-contacts + 200 + + 276 + + + + 3 + 12Put + ./devinf11 + 200 + + + 4 + 13 + application/vnd.syncml-devinf+xml + + ./devinf11 + + + Small Factory, Ltd. + Tiny Server + Tiny Shop + 485749KR + Server + + ./contacts + Addressbook + + text/x-vcard + 2.1 + + + text/vcard + 3.0 + + + text/x-vcard + 2.1 + + + text/vcard + 3.0 + + + + text/x-vcard + BEGIN + VCARD + END + VCARD + VERSION + 2.1 + N + TEL + VOICE + CELL + text/vcard + BEGIN + VCARD + END + VCARD + VERSION + 3.0 + N + TEL + VOICE + FAX + CELL + + + 01 + 02 + 07 + + + + + + + 5 + 201 + + ./dev-contacts + ./contacts/james_bond + + + 200005021T081812Z + 200005022T093223Z + + + + + + + diff --git a/tests/syncml/syncml-005.xml b/tests/syncml/syncml-005.xml new file mode 100644 index 0000000..689d048 --- /dev/null +++ b/tests/syncml/syncml-005.xml @@ -0,0 +1,55 @@ + + + + + 1.1 + SyncML/1.1 + 1 + 2 + http://www.syncml.org/sync-server + IMEI:493005100592800 + + + + 1 + 10SyncHdr + IMEI:493005100592800 + http://www.syncml.org/sync-server + 212 + + + 2 + 15Alert + ./dev-contacts + ./contacts/james_bond + 200 + + + 200005022T093223Z + + + + + 3 + ./contacts/james_bond + ./dev-contacts + + + 8100 + + 81 + + + + + 4 + text/x-vcard + + 1012 + + + + + + + diff --git a/tests/syncml/syncml-006.xml b/tests/syncml/syncml-006.xml new file mode 100644 index 0000000..2613d0e --- /dev/null +++ b/tests/syncml/syncml-006.xml @@ -0,0 +1,56 @@ + + + + + 1.1 + SyncML/1.1 + 1 + 2 + IMEI:493005100592800 + http://www.syncml.org/sync-server + + + + 1 + 20SyncHdr + http://www.syncml.org/sync-server + IMEI:493005100592800 + 200 + + + 2 + 23Sync + ./contacts/james_bond + ./dev-contacts + 200 + + + 3 + 24Replace + 1012 + 200 + + + 4 + ./dev-contacts + ./contacts/james_bond + + 5 + text/x-vcard + + 1023 + + + + + 6 + text/x-vcard + + 10536681 + + + + + + + \ No newline at end of file diff --git a/tests/syncml/syncml-007.xml b/tests/syncml/syncml-007.xml new file mode 100644 index 0000000..4e23ac0 --- /dev/null +++ b/tests/syncml/syncml-007.xml @@ -0,0 +1,50 @@ + + + + + 1.1 + SyncML/1.1 + 1 + 3 + http://www.syncml.org/sync-server + IMEI:493005100592800 + + + + 1 + 20SyncHdr + IMEI:493005100592800 + http://www.syncml.org/sync-server + 200 + + + 2 + 24Sync + ./dev-contacts + ./contacts/james_bond + 200 + + + 3 + 25Replace + 1023 + 200 + + + 4 + 26Add + 10536681 + 200 + + + 5 + ./contacts/james_bond + ./dev-contacts + + 10536681 + 1024 + + + + + \ No newline at end of file diff --git a/tests/syncml/syncml-008.xml b/tests/syncml/syncml-008.xml new file mode 100644 index 0000000..4a132b5 --- /dev/null +++ b/tests/syncml/syncml-008.xml @@ -0,0 +1,29 @@ + + + + + 1.1 + SyncML/1.1 + 1 + 3 + IMEI:493005100592800 + http://www.syncml.org/sync-server + + + + 1 + 30SyncHdr + http://www.syncml.org/sync-server + IMEI:493005100592800 + 200 + + + 1 + 35Map + ./contacts/james_bond + ./dev-contacts + 200 + + + + diff --git a/tests/syncml/syncml-009.xml b/tests/syncml/syncml-009.xml new file mode 100644 index 0000000..f86e929 --- /dev/null +++ b/tests/syncml/syncml-009.xml @@ -0,0 +1,54 @@ + + + + + 1.1 + SyncML/1.1 + 1 + 1 + http://www.syncml.org/sync-server + IMEI:493005100592800 + + syncml:auth-basic + QnJ1Y2UyOk9oQmVoYXZl + + + + + 1 + 200 + + ./contacts/james_bond + ./dev-contacts + + + 234 + 276 + + + + + + 2 + ./contacts/james_bond + ./dev-contacts + + + 8100 + + 81 + + + + + 3 + text/x-vcard + + 1012 + + + + + + + diff --git a/tests/syncml/syncml-010.xml b/tests/syncml/syncml-010.xml new file mode 100644 index 0000000..af6940e --- /dev/null +++ b/tests/syncml/syncml-010.xml @@ -0,0 +1,80 @@ + + + + + 1.1 + SyncML/1.1 + 1 + 1 + IMEI:493005100592800 + http://www.syncml.org/sync-server + + + + 1 + 10SyncHdr + http://www.syncml.org/sync-server + IMEI:493005100592800 + 212 + + + 2 + 11Alert + ./contacts/james_bond + ./dev-contacts + 200 + + 276 + + + + 3 + 12Sync + ./contacts/james_bond + ./dev-contacts + 200 + + + 4 + 13Replace + 1012 + 200 + + + 5 + 200 + + ./dev-contacts + ./contacts/james_bond + + + 200005021T081812Z + 200005022T093223Z + + + + + + 6 + ./dev-contacts + ./contacts/james_bond + + 7 + text/x-vcard + + 1023 + + + + + 8 + text/x-vcard + + 10536681 + + + + + + + diff --git a/tests/syncml/syncml-011.xml b/tests/syncml/syncml-011.xml new file mode 100644 index 0000000..c93a39a --- /dev/null +++ b/tests/syncml/syncml-011.xml @@ -0,0 +1,75 @@ + + + + 1.1 + Big Factory, Ltd. + 4119 + Jane's phones + 2.0e + 2.0 + 1.22I + 1218182THD000001-2 + phone + + + + + ./contacts + Phonebook + 32 + + text/vcard + 3.0 + + + text/vcard + 3.0 + + + text/x-vcard + 2.1 + + + 32650 + 250 + + + 1 + 7 + + + + text/x-vcard + BEGIN + VCARD + END + VCARD + VERSION + 2.1 + N + TEL + VOICE + FAX + CELL + text/vcard + BEGIN + VCARD + END + VCARD + VERSION + 3.0 + N + TEL + VOICE + FAX + CELL + + + srtmsg + Hello World + + + endmsg + Goodbye + + \ No newline at end of file diff --git a/tests/syncml/syncml-012.xml b/tests/syncml/syncml-012.xml new file mode 100644 index 0000000..f8d6d8e --- /dev/null +++ b/tests/syncml/syncml-012.xml @@ -0,0 +1,51 @@ + + + + + 1.1 + DM/1.1 + 0 + 0 + + My_SyncML_DM_Device + + + http://www.TheUltimateManagementServer.com + + + + + 1 + + + + ./SyncML/DMAcc/UltimateManagement + + + + node + + + + + + ./SyncML/DMAcc/UltimateManagement/Addr + + www.TheUltimateManagementServer.com + + + + ./SyncML/Con/My_ISP + + + + + ./SyncML/Con/My_ISP/PX/Addr + + 123.123.123.123 + + + + + + \ No newline at end of file diff --git a/tests/syncml/syncml-013.xml b/tests/syncml/syncml-013.xml new file mode 100644 index 0000000..9a024a7 --- /dev/null +++ b/tests/syncml/syncml-013.xml @@ -0,0 +1,32 @@ + + + + + + + 6 + text/x-vcard + + + pas-id-3F4B790300000000 + + BEGIN:VCARD +VERSION:2.1 +X-EVOLUTION-FILE-AS:Ximian, Inc. +N: +LABEL;WORK;ENCODING=QUOTED-PRINTABLE:401 Park Drive 3 West=0ABoston, MA +02215=0AUSA +TEL;WORK;VOICE:(617) 236-0442 +TEL;WORK;FAX:(617) 236-8630 +EMAIL;INTERNET:[EMAIL PROTECTED] +URL:www.ximian.com/ +ORG:Ximian, Inc. +NOTE:Welcome to the Ximian Addressbook. +UID:pas-id-3F4B790300000000 +END:VCARD + + + + + + \ No newline at end of file diff --git a/tests/syncml/syncml-014.xml b/tests/syncml/syncml-014.xml new file mode 100644 index 0000000..04eea5a --- /dev/null +++ b/tests/syncml/syncml-014.xml @@ -0,0 +1,34 @@ + + + + + + + 6 + text/x-vcard + + + pas-id-3F4B790300000000 + + + + + + + + + \ No newline at end of file diff --git a/tests/testsuite.xml b/tests/testsuite.xml new file mode 100644 index 0000000..ec8dbe8 --- /dev/null +++ b/tests/testsuite.xml @@ -0,0 +1,662 @@ + + + + + + Specification Example + + + mailbox (Encoded: 0x06) + + + mailbox: mailat: (Encoded: 0x07) + + + mailbox: pop:// (Encoded: 0x08) + + + mailbox: imap:// (Encoded: 0x09) + + + mailbox: http:// (Encoded: 0x0a) + + + mailbox: http://www. (Encoded: 0x0b) + + + mailbox: https:// (Encoded: 0x0c) + + + mailbox: https://www. (Encoded: 0x0d) + + + mailbox: .com (Encoded: 0x85) + + + mailbox: .edu (Encoded: 0x86) + + + mailbox: .net (Encoded: 0x87) + + + mailbox: .org (Encoded: 0x88) + + + timestamp: 2002-04-16T06:40:00Z + + + timestamp: 2002-04-16T06:00:00Z + + + timestamp: 2002-04-16T00:00:00Z + + + Empty timestamp and mailbox attributes + + + + + + Specification Example + + + Simpliest document: Empty Indication. + + + Full document: All possible elements and attributes + + + Indication attribute action: signal-none + + + Indication attribute action: signal-low + + + Indication attribute action: signal-medium + + + Indication attribute action: signal-high + + + Indication attribute action: delete + + + Indication attribute href: wap.* (Encoded: 0x0B) + + + Indication attribute href: http://wap.* (Encoded: 0x0C) + + + Indication attribute href: http://www.* (Encoded: 0x0D) + + + Indication attribute href: https://wap.* (Encoded: 0x0E) + + + Indication attribute href: https://www.* (Encoded: 0x0F) + + + Indication attribute si-id + + + Indication attribute si-id empty + + + Indication attribute created + + + Indication attribute created empty + + + Indication attribute si-expires + + + Indication attribute si-expires empty + + + Info element with one item + + + Info element with several item + + + Indication attribute href: https//www.yahoo.com/ ("https//www" and ".com/" encoded) + + + Indication attribute created: 1999-06-25T15:23:00Z + + + Indication attribute created: 1999-06-25T15:00:00Z + + + Indication attribute created: 1999-06-25T00:00:00Z + + + + + + Specification Example + + + Empty href attribute value + + + action : execute-low + + + action : execute-high + + + action : cache + + + href: http:// (Encoded: 0x09) + + + href: http://www. (Encoded: 0x0A) + + + href: https:// (Encoded: 0x0B) + + + href: https://www. (Encoded: 0x0C) + + + href: .com (Encoded: 0x85) + + + href: .edu (Encoded: 0x86) + + + href: .net (Encoded: 0x87) + + + href: .org (Encoded: 0x88) + + + + + + Specification Example 1 + + + Specification Example 2 + + + Specification Example 3 + + + Specification Example 4 + + + Specification Example 5 + + + Specification Example 6 + + + Specification Example 7 + + + Specification Example 8 + + + + + + Specification GSM/CSD Settings Set + + + Specification GSM/GPRS Settings Set + + + + + + + Specification Example: STATUS PRIMITIVE WITH DETAILS + + + Specification Example: POLLING-REQUEST PRIMITIVE + + + Specification Example: 2-WAY LOGIN TRANSACTION - Login-Request primitive + + + Specification Example: 2-WAY LOGIN TRANSACTION - Login-Response primitive + + + Specification Example: 4-WAY LOGIN TRANSACTION - Login-Request primitive + + + Specification Example: 4-WAY LOGIN TRANSACTION - Login-Response primitive + + + Specification Example: 4-WAY LOGIN TRANSACTION - Login-Request primitive + + + Specification Example: 4-WAY LOGIN TRANSACTION - Login-Response primitive + + + Specification Example: SERVICE NEGOTIATION TRANSACTION - Service-Request primitive + + + Specification Example: SERVICE NEGOTIATION TRANSACTION - Service-Response primitive + + + Specification Example: CLIENT CAPABILITY NEGOTATION TRANSACTION - ClientCapability-Request primitive + + + Specification Example: CLIENT CAPABILITY NEGOTATION TRANSACTION - ClientCapability-Response primitive + + + Specification Example: LOGOUT TRANSACTION - Logout-Request primitive + + + Specification Example: LOGOUT TRANSACTION - Disconnect primitive + + + Specification Example: SERVER INITIATED LOGOUT TRANSACTION - Disconnect primitive + + + Specification Example: TIME-OUT RESET TRANSACTION - KeepAlive-Request primitive + + + Specification Example: TIME-OUT RESET TRANSACTION - KeepAlive-Response primitive + + + Specification Example: GET SERVICE PROVIDER INFO TRANSACTION - GetSPInfo-Request primitive + + + Specification Example: GET SERVICE PROVIDER INFO TRANSACTION - GetSPInfo-Response primitive + + + Specification Example: GENERAL SEARCH TRANSACTION - Search-Request (1st) primitive + + + Specification Example: GENERAL SEARCH TRANSACTION - Search-Response (1st) primitive + + + Specification Example: GENERAL SEARCH TRANSACTION - Search-Request (continued) primitive + + + Specification Example: GENERAL SEARCH TRANSACTION - Search-Response (continued) primitive + + + Specification Example: GENERAL SEARCH TRANSACTION - StopSearch-Request primitive + + + Specification Example: GENERAL SEARCH TRANSACTION - Status primitive + + + Specification Example: GENERAL INVITATION TRANSACTION - Invite-Request primitive + + + Specification Example: GENERAL INVITATION TRANSACTION - Status primitive + + + Specification Example: GENERAL INVITATION TRANSACTION - InviteUser-Request primitive + + + Specification Example: GENERAL INVITATION TRANSACTION - Status primitive + + + Specification Example: GENERAL INVITATION TRANSACTION - InviteUser-Response primitive + + + Specification Example: GENERAL INVITATION TRANSACTION - Status primitive + + + Specification Example: GENERAL INVITATION TRANSACTION - Invite-Response primitive + + + Specification Example: GENERAL INVITATION TRANSACTION - Status primitive + + + Specification Example: RECALL INVITATION TRANSACTION - CancelInvite-Request primitive + + + Specification Example: RECALL INVITATION TRANSACTION - Status primitive + + + Specification Example: RECALL INVITATION TRANSACTION - CancelInviteUser-Request primitive + + + Specification Example: RECALL INVITATION TRANSACTION - Status primitive + + + Specification Example: SUBSCRIBE/UNSUBSCRIBE PRESENCE TRANSACTION - SubscribePresence-Request primitive + + + Specification Example: SUBSCRIBE/UNSUBSCRIBE PRESENCE TRANSACTION - Status primitive + + + Specification Example: SUBSCRIBE/UNSUBSCRIBE PRESENCE TRANSACTION - PresenceNotification-Request primitive + + + Specification Example: SUBSCRIBE/UNSUBSCRIBE PRESENCE TRANSACTION - Status primitive + + + Specification Example: SUBSCRIBE/UNSUBSCRIBE PRESENCE TRANSACTION - UnsubscribePresence-Request primitive + + + Specification Example: SUBSCRIBE/UNSUBSCRIBE PRESENCE TRANSACTION - Status primitive + + + Specification Example: GET WATCHER LIST TRANSACTION - GetWatcherList-Request primitive + + + Specification Example: GET WATCHER LIST TRANSACTION - GetWatcherList-Response primitive + + + Specification Example: GET PRESENCE TRANSACTION - GetPresence-Request primitive + + + Specification Example: GET PRESENCE TRANSACTION - GetPresence-Response primitive + + + Specification Example: REACTIVE PRESENCE AUTHORIZATION TRANSACTION - PresenceAuth-Request primitive + + + Specification Example: REACTIVE PRESENCE AUTHORIZATION TRANSACTION - Status primitive + + + Specification Example: REACTIVE PRESENCE AUTHORIZATION TRANSACTION - PresenceAuth-User primitive + + + Specification Example: REACTIVE PRESENCE AUTHORIZATION TRANSACTION - Status primitive + + + Specification Example: CANCEL PRESENCE AUTHORIZATION TRANSACTION - CancelAuth-Request primitive + + + Specification Example: CANCEL PRESENCE AUTHORIZATION TRANSACTION - Status primitive + + + Specification Example: UPDATE PRESENCE TRANSACTION - UpdatePresence-Request primitive + + + Specification Example: UPDATE PRESENCE TRANSACTION - Status primitive + + + Specification Example: SEND MESSAGE TRANSACTION - SendMessage-Request primitive + + + Specification Example: SEND MESSAGE TRANSACTION - SendMessage-Response primitive + + + Specification Example: SET DELIVERY METHOD TRANSACTION - SetDeliveryMethod-Request primitive + + + Specification Example: SET DELIVERY METHOD TRANSACTION - Status primitive + + + Specification Example: GET LIST OF UNDELIVERED MESSAGES TRANSACTION - GetMessageList-Request primitive + + + Specification Example: GET LIST OF UNDELIVERED MESSAGES TRANSACTION - GetMessageList-Response primitive + + + Specification Example: REJECTING A MESSAGE (NOTIFY/GET METHOD ONLY) TRANSACTION - RejectMessage-Request primitive + + + Specification Example: REJECTING A MESSAGE (NOTIFY/GET METHOD ONLY) TRANSACTION - Status primitive + + + Specification Example: MESSAGE NOTIFICATION (NOTIFY/GET METHOD ONLY) TRANSACTION - MessageNotification primitive + + + Specification Example: MESSAGE NOTIFICATION (NOTIFY/GET METHOD ONLY) TRANSACTION - Status primitive + + + Specification Example: RETRIEVING A MESSAGE (GET/NOTIFY METHOD) TRANSACTION - GetMessage-Request primitive + + + Specification Example: RETRIEVING A MESSAGE (GET/NOTIFY METHOD) TRANSACTION - GetMessage-Response primtive + + + Specification Example: RETRIEVING A MESSAGE (GET/NOTIFY METHOD) TRANSACTION - MessageDelivered primitive + + + Specification Example: RETRIEVING A MESSAGE (GET/NOTIFY METHOD) TRANSACTION - Status primitive + + + Specification Example: DELIVERING A MESSAGE (PUSH METHOD) TRANSACTION - NewMessage primitive + + + Specification Example: DELIVERING A MESSAGE (PUSH METHOD) TRANSACTION - MessageDelivered primitive + + + Specification Example: DELIVERY REPORT TRANSACTION - DeliveryReport-Request primitive + + + Specification Example: DELIVERY REPORT TRANSACTION - Status primitive + + + Specification Example: FORWARD UNDELIVERED MESSAGE TRANSACTION - ForwardMessage-Request primitive + + + Specification Example: FORWARD UNDELIVERED MESSAGE TRANSACTION - Status primitive + + + Specification Example: GET BLOCKED USER LIST TRANSACTION - GetBlockedList-Request primitive + + + Specification Example: GET BLOCKED USER LIST TRANSACTION - GetBlockedList-Response primitive + + + Specification Example: BLOCK ENTITY TRANSACTION - BlockEntity-Request primitive + + + Specification Example: BLOCK ENTITY TRANSACTION - Status primitive + + + Specification Example: GET LIST OF CONTACT LIST(S) TRANSACTION - GetList-Request primitive + + + Specification Example: GET LIST OF CONTACT LIST(S) TRANSACTION - GetList-Response primitive + + + Specification Example: CREATE CONTACT LIST TRANSACTION - CreateList-Request primitive + + + Specification Example: CREATE CONTACT LIST TRANSACTION - Status primitive + + + Specification Example: DELETE CONTACT LIST TRANSACTION - DeleteList-Request primitive + + + Specification Example: DELETE CONTACT LIST TRANSACTION - Status primitive + + + Specification Example: RETRIEVE CONTACT LIST TRANSACTION - ListManage-Request primitive + + + Specification Example: RETRIEVE CONTACT LIST TRANSACTION - ListManage-Response primitive + + + Specification Example: ADD USERS TO CONTACT LIST TRANSACTION - ListManage-Request primitive + + + Specification Example: ADD USERS TO CONTACT LIST TRANSACTION - ListManage-Response primitive + + + Specification Example: REMOVE USERS FROM CONTACT LIST TRANSACTION - ListManage-Request primitive + + + Specification Example: REMOVE USERS FROM CONTACT LIST TRANSACTION - ListManage-Response primitive + + + Specification Example: MODIFY PROPERTIES OF CONTACT LIST TRANSACTION - ListManage-Request primitive + + + Specification Example: MODIFY PROPERTIES OF CONTACT LIST TRANSACTION - ListManage-Response primitive + + + Specification Example: CREATE ATTRIBUTE LIST TRANSACTION - CreateAttributeList-Request primitive + + + Specification Example: CREATE ATTRIBUTE LIST TRANSACTION - Status primitive + + + Specification Example: DELETE ATTRIBUTE LIST TRANSACTION - DeleteAttributeList-Request primitive + + + Specification Example: DELETE ATTRIBUTE LIST TRANSACTION - Status primitive + + + Specification Example: GET ATTRIBUTE LIST TRANSACTION - GetAttributeList-Request primitive + + + Specification Example: GET ATTRIBUTE LIST TRANSACTION - GetAttributeList-Response primitive + + + Specification Example: CREATE GROUP TRANSACTION - CreateGroup-Request primitive + + + Specification Example: CREATE GROUP TRANSACTION - Status primitive + + + Specification Example: DELETE GROUP TRANSACTION - DeleteGroup-Request primitive + + + Specification Example: DELETE GROUP TRANSACTION - Status primitive + + + Specification Example: JOIN GROUP TRANSACTION - JoinGroup-Request primitive + + + Specification Example: JOIN GROUP TRANSACTION - JoinGroup-Response primitive + + + Specification Example: USER INITIATED LEAVE GROUP TRANSACTION - LeaveGroup-Request primitive + + + Specification Example: USER INITIATED LEAVE GROUP TRANSACTION - LeaveGroup-Response primitive + + + Specification Example: SERVER INITIATED LEAVE GROUP TRANSACTION - LeaveGroup-Response primitive + + + Specification Example: SERVER INITIATED LEAVE GROUP TRANSACTION - Status primitive + + + Specification Example: GET GROUP MEMBER LIST TRANSACTION - GetGroupMembers-Request primitive + + + Specification Example: GET GROUP MEMBER LIST TRANSACTION - GetGroupMemb ers-Response primitive + + + Specification Example: ADD GROUP MEMBERS TO A GROUP TRANSACTION - AddGroupMembers-Request primitive + + + Specification Example: ADD GROUP MEMBERS TO A GROUP TRANSACTION - Status primitive + + + Specification Example: REMOVE GROUP MEMBERS FROM A GROUP TRANSACTION - RemoveGroupMembers-Request primitive + + + Specification Example: REMOVE GROUP MEMBERS FROM A GROUP TRANSACTION - Status primitive + + + Specification Example: CHANGING ACCESS RIGHTS IN A GROUP TRANSACTION - MemberAccess-Request primitive + + + Specification Example: CHANGING ACCESS RIGHTS IN A GROUP TRANSACTION - Status primitive + + + Specification Example: MODIFY GROUP PROPERTIES TRANSACTION - GetGroupProps-Request primitive + + + Specification Example: MODIFY GROUP PROPERTIES TRANSACTION - GetGroupProps-Response primitive + + + Specification Example: MODIFY GROUP PROPERTIES TRANSACTION - SetGroupProps-Request primitive + + + Specification Example: MODIFY GROUP PROPERTIES TRANSACTION - Status primitive + + + Specification Example: REJECT USER FROM GROUP TRANSACTION - RejectList-Request primitive + + + Specification Example: REJECT USER FROM GROUP TRANSACTION - RejectList-Response primitive + + + Specification Example: SUBSCRIBE GROUP CHANGE NOTIFICATION TRANSACTION - SubscribeGroupNotice-Request primitive (get) + + + Specification Example: SUBSCRIBE GROUP CHANGE NOTIFICATION TRANSACTION - SubscribeGroupNotice-Response primitive + + + Specification Example: SUBSCRIBE GROUP CHANGE NOTIFICATION TRANSACTION - SubscribeGroupNotice-Request primitive (set) + + + Specification Example: SUBSCRIBE GROUP CHANGE NOTIFICATION TRANSACTION - Status primitive + + + Specification Example: SUBSCRIBE GROUP CHANGE NOTIFICATION TRANSACTION - GroupChangeNotice primitive + + + Specification Example: SUBSCRIBE GROUP CHANGE NOTIFICATION TRANSACTION - Status primitive + + + + + + Specification Example - Example of Busy Status + + + Specification Example - Example of Result Alert + + + Specification Example - Example of Sync Initialization Package from Client + + + Specification Example - Example of Sync Initialization Package from Server + + + Specification Example - Example of Sending Modifications to Server + + + Specification Example - Example of Sending Modifications to Client + + + Specification Example - Example of Data Update Status to Server + + + Specification Example - Example of Map Acknowledge + + + Specification Example - Example of Sync without Separate Initialization + + + Specification Example - Example of Sync without Separate Initialization + + + DevInf Specification Example + + + SyncML DM Boot: Example bootstrap message + + + Test of VCard data, without CDATA + + + Test of VCard data, with CDATA + + + diff --git a/tests/wv/wv-001.xml b/tests/wv/wv-001.xml new file mode 100644 index 0000000..8875f99 --- /dev/null +++ b/tests/wv/wv-001.xml @@ -0,0 +1,52 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 201 + + Partially successful. + + + 531 + + Unknown user. + + wv:bad_user1@im.com + + wv:bad_user2@im.com + + + + 532 + + Blocked. + + wv:bad_user3@im.com + + wv:bad_user4@im.com + + + + + + + + diff --git a/tests/wv/wv-002.xml b/tests/wv/wv-002.xml new file mode 100644 index 0000000..3dfc2c7 --- /dev/null +++ b/tests/wv/wv-002.xml @@ -0,0 +1,25 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + + + The Wireless Village initiative: CSP DTD and examples v1.1 WV-023 + + + + + + + + diff --git a/tests/wv/wv-003.xml b/tests/wv/wv-003.xml new file mode 100644 index 0000000..00b6d10 --- /dev/null +++ b/tests/wv/wv-003.xml @@ -0,0 +1,34 @@ + + + + + + Outband + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:user@im.com + + + http://206.226.10.25:80/IMPSAPP + + + 1my2pass3word + + 120 + + im.user.com#20011224#328746293 + + + + + + diff --git a/tests/wv/wv-004.xml b/tests/wv/wv-004.xml new file mode 100644 index 0000000..c79f9d0 --- /dev/null +++ b/tests/wv/wv-004.xml @@ -0,0 +1,40 @@ + + + + + + Outband + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + http://206.226.10.25:80/IMPSAPP + + + + 200 + + Successfully logged in. + + + im.user.com#48815@server.com + + 120 + + T + + + + + + diff --git a/tests/wv/wv-005.xml b/tests/wv/wv-005.xml new file mode 100644 index 0000000..58c8304 --- /dev/null +++ b/tests/wv/wv-005.xml @@ -0,0 +1,32 @@ + + + + + + Outband + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:user@im.com + + + http://206.226.10.25:80/IMPSAPP + + + PWD,SHA,MD4,MD5,MD6 + + im.user.com#20011224#328746293 + + + + + + diff --git a/tests/wv/wv-006.xml b/tests/wv/wv-006.xml new file mode 100644 index 0000000..7343ccc --- /dev/null +++ b/tests/wv/wv-006.xml @@ -0,0 +1,40 @@ + + + + + + Outband + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + http://206.226.10.25:80/IMPSAPP + + + + 200 + + Successfully logged in. + + + 92387rhf934fho3fh9fkn309fn3pfun304ufn3 + + MD6 + + F + + + + + + diff --git a/tests/wv/wv-007.xml b/tests/wv/wv-007.xml new file mode 100644 index 0000000..d7812a9 --- /dev/null +++ b/tests/wv/wv-007.xml @@ -0,0 +1,34 @@ + + + + + + Outband + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:user@im.com + + + http://206.226.10.25:80/IMPSAPP + + + alkkuayfdsAKDSJfsdfjhksadhlkasdlkfgsal + + 120 + + im.user.com#20011224#328746293 + + + + + + diff --git a/tests/wv/wv-008.xml b/tests/wv/wv-008.xml new file mode 100644 index 0000000..c79f9d0 --- /dev/null +++ b/tests/wv/wv-008.xml @@ -0,0 +1,40 @@ + + + + + + Outband + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + http://206.226.10.25:80/IMPSAPP + + + + 200 + + Successfully logged in. + + + im.user.com#48815@server.com + + 120 + + T + + + + + + diff --git a/tests/wv/wv-009.xml b/tests/wv/wv-009.xml new file mode 100644 index 0000000..58fd05b --- /dev/null +++ b/tests/wv/wv-009.xml @@ -0,0 +1,40 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + http://206.226.10.25:80/IMPSAPP + + + + + + + + + + + + + T + + + + + + diff --git a/tests/wv/wv-010.xml b/tests/wv/wv-010.xml new file mode 100644 index 0000000..13755a0 --- /dev/null +++ b/tests/wv/wv-010.xml @@ -0,0 +1,42 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + http://206.226.10.25:80/IMPSAPP + + + + + + + + + + + + + + + + + + + diff --git a/tests/wv/wv-011.xml b/tests/wv/wv-011.xml new file mode 100644 index 0000000..c2b5a74 --- /dev/null +++ b/tests/wv/wv-011.xml @@ -0,0 +1,68 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + http://206.226.10.25:80/IMPSAPP + + + + MOBILE_PHONE + + P + + text/plain; charset=us-ascii + + application/x-sms + + text/x-vCard; charset=us-ascii + + text/x-vCalendar; charset=us-ascii + + BASE64 + + 32767 + + SMS + + WSP + + HTTP + + 1 + + 32767 + + WAPSMS + + WAPUDP + + SUDP + + STCP + + 91 + + 2 + + + + + + + diff --git a/tests/wv/wv-012.xml b/tests/wv/wv-012.xml new file mode 100644 index 0000000..0e00194 --- /dev/null +++ b/tests/wv/wv-012.xml @@ -0,0 +1,74 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + http://206.226.10.25:80/IMPSAPP + + + + MOBILE_PHONE + + P + + text/plain; charset=us-ascii + + application/x-sms + + text/x-vCard; charset=us-ascii + + text/x-vCalendar; charset=us-ascii + + BASE64 + + 32767 + + SMS + + WSP + + HTTP + + 1 + + 32767 + + WAPSMS + + WAPUDP + + SUDP + + STCP + + 91 + + 100.100.100.100 + + 98 + + 3 + + + + + + + diff --git a/tests/wv/wv-013.xml b/tests/wv/wv-013.xml new file mode 100644 index 0000000..dc33cec --- /dev/null +++ b/tests/wv/wv-013.xml @@ -0,0 +1,24 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + + + + diff --git a/tests/wv/wv-014.xml b/tests/wv/wv-014.xml new file mode 100644 index 0000000..9fda75c --- /dev/null +++ b/tests/wv/wv-014.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + + + + + + diff --git a/tests/wv/wv-015.xml b/tests/wv/wv-015.xml new file mode 100644 index 0000000..c043029 --- /dev/null +++ b/tests/wv/wv-015.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 601 + + Updating server software. All services offline for 3 hours. + + + + + + + diff --git a/tests/wv/wv-016.xml b/tests/wv/wv-016.xml new file mode 100644 index 0000000..d9da61b --- /dev/null +++ b/tests/wv/wv-016.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + 20 + + + + + + diff --git a/tests/wv/wv-017.xml b/tests/wv/wv-017.xml new file mode 100644 index 0000000..a92976e --- /dev/null +++ b/tests/wv/wv-017.xml @@ -0,0 +1,34 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + 120 + + + + + + diff --git a/tests/wv/wv-018.xml b/tests/wv/wv-018.xml new file mode 100644 index 0000000..5621851 --- /dev/null +++ b/tests/wv/wv-018.xml @@ -0,0 +1,26 @@ + + + + + + Outband + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + http://206.226.10.25:80/IMPSAPP + + + + + + + diff --git a/tests/wv/wv-019.xml b/tests/wv/wv-019.xml new file mode 100644 index 0000000..09a8ff1 --- /dev/null +++ b/tests/wv/wv-019.xml @@ -0,0 +1,44 @@ + + + + + + Outband + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + http://206.226.10.25:80/IMPSAPP + + + Fake Chocholate Co. + + + application/vnd.wap.mms-message + + 1234 + + BASE64 + + Base64EncodedDataHere + + + We make the fakest chocholate in the world! + + http://www.fake-chocholate.co.uk + + + + + + diff --git a/tests/wv/wv-020.xml b/tests/wv/wv-020.xml new file mode 100644 index 0000000..dbb8bdc --- /dev/null +++ b/tests/wv/wv-020.xml @@ -0,0 +1,38 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + USER_LAST_NAME + + Smith + + + + USER_ONLINE_STATUS + + T + + + 5 + + + + + + diff --git a/tests/wv/wv-021.xml b/tests/wv/wv-021.xml new file mode 100644 index 0000000..c392960 --- /dev/null +++ b/tests/wv/wv-021.xml @@ -0,0 +1,59 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 0x23829381 + + 7 + + F + + 5 + + + + + wv:he@there.com + + + + wv:she@there.com + + + + wv:matthias@salamander.com + + + + wv:francisco@don.com + + + + wv:john@smith.com + + + + + + + + + diff --git a/tests/wv/wv-022.xml b/tests/wv/wv-022.xml new file mode 100644 index 0000000..8ba87a7 --- /dev/null +++ b/tests/wv/wv-022.xml @@ -0,0 +1,29 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12346@NOK5110 + + + + + + 0x23829381 + + 6 + + + + + + diff --git a/tests/wv/wv-023.xml b/tests/wv/wv-023.xml new file mode 100644 index 0000000..00b4053 --- /dev/null +++ b/tests/wv/wv-023.xml @@ -0,0 +1,47 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12346@NOK5110 + + F + + + + + + 0x23829381 + + 7 + + T + + 7 + + + + + wv:mary@site.com + + + + wv:anna@server.com + + + + + + + + + diff --git a/tests/wv/wv-024.xml b/tests/wv/wv-024.xml new file mode 100644 index 0000000..9ef6822 --- /dev/null +++ b/tests/wv/wv-024.xml @@ -0,0 +1,27 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12347@NOK5110 + + + + + + 0x23829381 + + + + + + diff --git a/tests/wv/wv-025.xml b/tests/wv/wv-025.xml new file mode 100644 index 0000000..5116d5a --- /dev/null +++ b/tests/wv/wv-025.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12347@NOK5110 + + F + + + + + + 200 + + + + + + + diff --git a/tests/wv/wv-026.xml b/tests/wv/wv-026.xml new file mode 100644 index 0000000..1b9760a --- /dev/null +++ b/tests/wv/wv-026.xml @@ -0,0 +1,58 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + 0x38382025 + + GR + + + + wv:he@there.com + + + + wv:she@there.com + + + + + Johnny + + wv:john/partygroup@there.com + + + + + wv:john/partygroup@there.com + + Come to party! You have 10 minutes! + + + WV + + wv:john/partygroup@there.com + + + 600 + + + + + + diff --git a/tests/wv/wv-027.xml b/tests/wv/wv-027.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-027.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-028.xml b/tests/wv/wv-028.xml new file mode 100644 index 0000000..32c4f3f --- /dev/null +++ b/tests/wv/wv-028.xml @@ -0,0 +1,46 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12346@NOK5110 + + F + + + + + 0x38382025 + + GR + + + + + WV + + wv:john/partygroup@there.com + + + + + wv:john/partygroup@there.com + + Come to party! + + 600 + + + + + + diff --git a/tests/wv/wv-029.xml b/tests/wv/wv-029.xml new file mode 100644 index 0000000..4274e4e --- /dev/null +++ b/tests/wv/wv-029.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12346@NOK5110 + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-030.xml b/tests/wv/wv-030.xml new file mode 100644 index 0000000..dde6a8f --- /dev/null +++ b/tests/wv/wv-030.xml @@ -0,0 +1,36 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12347@NOK5110 + + + + + 0x38382025 + + T + + OK, just a sec! + + + Johnny + + wv:john/partygroup@there.com + + + + + + + diff --git a/tests/wv/wv-031.xml b/tests/wv/wv-031.xml new file mode 100644 index 0000000..4ddca7a --- /dev/null +++ b/tests/wv/wv-031.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12347@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-032.xml b/tests/wv/wv-032.xml new file mode 100644 index 0000000..556cd5e --- /dev/null +++ b/tests/wv/wv-032.xml @@ -0,0 +1,42 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12348@NOK5110 + + F + + + + + 0x38382025 + + T + + + + + WV + + wv:john/partygroup@there.com + + + + + OK, just a sec! + + + + + + diff --git a/tests/wv/wv-033.xml b/tests/wv/wv-033.xml new file mode 100644 index 0000000..4913624 --- /dev/null +++ b/tests/wv/wv-033.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12348@NOK5110 + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-034.xml b/tests/wv/wv-034.xml new file mode 100644 index 0000000..4bd8c69 --- /dev/null +++ b/tests/wv/wv-034.xml @@ -0,0 +1,52 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + 0x38382025 + + + + wv:he@there.com + + + + wv:she@there.com + + + + + Johnny + + wv:john/partygroup@there.com + + + + + Time is up! + + + WV + + wv:john/partygroup@there.com + + + + + + + diff --git a/tests/wv/wv-035.xml b/tests/wv/wv-035.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-035.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-036.xml b/tests/wv/wv-036.xml new file mode 100644 index 0000000..e0b014b --- /dev/null +++ b/tests/wv/wv-036.xml @@ -0,0 +1,40 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12346@NOK5110 + + F + + + + + 0x38382025 + + + + + WV + + wv:john/partygroup@there.com + + + + + Time is up! + + + + + + diff --git a/tests/wv/wv-037.xml b/tests/wv/wv-037.xml new file mode 100644 index 0000000..4274e4e --- /dev/null +++ b/tests/wv/wv-037.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12346@NOK5110 + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-038.xml b/tests/wv/wv-038.xml new file mode 100644 index 0000000..b868df9 --- /dev/null +++ b/tests/wv/wv-038.xml @@ -0,0 +1,62 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/ContactList-5@smith.com + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/wv/wv-039.xml b/tests/wv/wv-039.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-039.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-040.xml b/tests/wv/wv-040.xml new file mode 100644 index 0000000..92200b8 --- /dev/null +++ b/tests/wv/wv-040.xml @@ -0,0 +1,142 @@ + + + + + + Inband + im.user.com#48815@server.com + + + + Request + IMApp01#12346@NOK5110 + F + + + + + wv:he@there.com + + + T + T + + + T + T + + + T + MOBILE_PHONE + ABC Company + xyz200 + fin + + + T + +02 + + + T + 35 24 15.652W + 12 36 22.5N + 200 + +
+ T + GB + London +
+ + T + At home + + + T + Sonera + + + T + + CALL + OPEN + +35804123123 + I am using this phone during office hours + + + CALL + CLOSED + +35805456456 + + I am using this phone outside office hours + + + + IM + OPEN + he@there.com + My IM-application is now online + + + + T + AVAILABLE + + + T + + CALL + +35804123123 + OPEN + Home Phone + 10 + + + SMS + +35804123123 + OPEN + Home Messaging + 20 + + + IM + ari@im.com + CLOSED + Private IM + 30 + + + + T + fin + + + T + Busy editing a document + + + + T + SLEEPY + + + T + He + + + T + http://www.foo.com/MyLogo + + + + T + http://www.foo.com/MyCard + + +
+
+
+
+
+
+
diff --git a/tests/wv/wv-041.xml b/tests/wv/wv-041.xml new file mode 100644 index 0000000..4274e4e --- /dev/null +++ b/tests/wv/wv-041.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12346@NOK5110 + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-042.xml b/tests/wv/wv-042.xml new file mode 100644 index 0000000..efe01c7 --- /dev/null +++ b/tests/wv/wv-042.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12347@NOK5110 + + + + + wv:john/ContactList-5@smith.com + + + + + + diff --git a/tests/wv/wv-043.xml b/tests/wv/wv-043.xml new file mode 100644 index 0000000..4ddca7a --- /dev/null +++ b/tests/wv/wv-043.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12347@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-044.xml b/tests/wv/wv-044.xml new file mode 100644 index 0000000..9418bb9 --- /dev/null +++ b/tests/wv/wv-044.xml @@ -0,0 +1,24 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + + + + diff --git a/tests/wv/wv-045.xml b/tests/wv/wv-045.xml new file mode 100644 index 0000000..05e5ac0 --- /dev/null +++ b/tests/wv/wv-045.xml @@ -0,0 +1,34 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + wv:he@there.com + + + + wv:she@there.com + + + + + + + diff --git a/tests/wv/wv-046.xml b/tests/wv/wv-046.xml new file mode 100644 index 0000000..88202ed --- /dev/null +++ b/tests/wv/wv-046.xml @@ -0,0 +1,68 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + wv:he@there.com + + + + wv:she@there.com + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/wv/wv-047.xml b/tests/wv/wv-047.xml new file mode 100644 index 0000000..7738c18 --- /dev/null +++ b/tests/wv/wv-047.xml @@ -0,0 +1,406 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + wv:he@there.com + + + + T + + T + + + + T + + T + + + + T + + MOBILE_PHONE + + ABC Company + + xyz200 + + fin + + + + T + + +02 + + + + T + + 35 24 15.652W + + 12 36 22.5N + + 200 + + +
+ T + + GB + + London +
+ + + T + + At home + + + + T + + Sonera + + + + T + + + CALL + + OPEN + + +35804123123 + + I am using this phone during office hours + + + + CALL + + CLOSED + + +35805456456 + + I am using this phone outside office hours + + + + IM + + OPEN + + he@there.com + + My IM-application is now online + + + + IM + + OPEN + + he@there.com + + My IM-application is now online + + + + + T + + AVAILABLE + + + + T + + + CALL + + +35804123123 + + OPEN + + Home Phone + + 10 + + + + SMS + + +35804123123 + + OPEN + + Home Messaging + + 20 + + + + IM + + ari@im.com + + CLOSED + + Private IM + + 30 + + + + + T + + fin + + + + T + + Busy editing a document + + + + T + + SLEEPY + + + + T + + He + + + + T + + http://www.foo.com/MyLogo + + + + T + + http://www.foo.com/MyCard + +
+
+ + + wv:she@there.com + + + + T + + T + + + + T + + T + + + + T + + MOBILE_PHONE + + ABC Company + + xyz200 + + fin + + + + T + + +02 + + + + T + + 35 24 15.652W + + 12 36 22.5N + + 200 + + +
+ T + + GB + + London +
+ + + T + + At home + + + + T + + Sonera + + + + T + + + CALL + + OPEN + + +35804123123 + + I am using this phone during office hours + + + + CALL + + CLOSED + + +35805456456 + + I am using this phone outside office hours + + + + IM + + OPEN + + she@there.com + + My IM-application is now online + + + + + T + + AVAILABLE + + + + T + + + CALL + + +35804123123 + + OPEN + + Business Phone + + 10 + + + + SMS + + +35804123123 + + OPEN + + Business Messaging + + 20 + + + + IM + + ari@im.com + + CLOSED + + Private IM + + 30 + + + + + T + + fin + + + + T + + Busy editing a document + + + + T + + SLEEPY + + + + T + + She + + + + T + + BASE64EncodedDataHere + + + + T + + vCardDataHere + +
+
+
+
+
+
+
+ diff --git a/tests/wv/wv-048.xml b/tests/wv/wv-048.xml new file mode 100644 index 0000000..c06f085 --- /dev/null +++ b/tests/wv/wv-048.xml @@ -0,0 +1,62 @@ + + + + + + Outband + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + wv:matthias@salamander.com + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/wv/wv-049.xml b/tests/wv/wv-049.xml new file mode 100644 index 0000000..f98d1c6 --- /dev/null +++ b/tests/wv/wv-049.xml @@ -0,0 +1,28 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + + + + + 200 + + + + + + + diff --git a/tests/wv/wv-050.xml b/tests/wv/wv-050.xml new file mode 100644 index 0000000..5a2405d --- /dev/null +++ b/tests/wv/wv-050.xml @@ -0,0 +1,28 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12346@NOK5110 + + + + + wv:matthias@salamander.com + + T + + + + + + diff --git a/tests/wv/wv-051.xml b/tests/wv/wv-051.xml new file mode 100644 index 0000000..bf886f8 --- /dev/null +++ b/tests/wv/wv-051.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12346@NOK5110 + + F + + + + + + 200 + + + + + + + diff --git a/tests/wv/wv-052.xml b/tests/wv/wv-052.xml new file mode 100644 index 0000000..b8024a8 --- /dev/null +++ b/tests/wv/wv-052.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:matthias@salamander.com + + + + + + diff --git a/tests/wv/wv-053.xml b/tests/wv/wv-053.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-053.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-054.xml b/tests/wv/wv-054.xml new file mode 100644 index 0000000..9594201 --- /dev/null +++ b/tests/wv/wv-054.xml @@ -0,0 +1,38 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + + T + + on the way home + + + + T + + HAPPY + + + + + + + + diff --git a/tests/wv/wv-055.xml b/tests/wv/wv-055.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-055.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-056.xml b/tests/wv/wv-056.xml new file mode 100644 index 0000000..0924911 --- /dev/null +++ b/tests/wv/wv-056.xml @@ -0,0 +1,62 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + T + + + text/plain + + None + + 58 + + + + wv:he@there.com + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + wv:john/My_friends@smith.com + + + + + wv:john@smith.com + + + + 20010925T1340Z + + 600 + + + Hurry up; they are ringing the bells in the WV already... + + + + + + diff --git a/tests/wv/wv-057.xml b/tests/wv/wv-057.xml new file mode 100644 index 0000000..c4a8c71 --- /dev/null +++ b/tests/wv/wv-057.xml @@ -0,0 +1,34 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + 0x0000f132 + + + + + + diff --git a/tests/wv/wv-058.xml b/tests/wv/wv-058.xml new file mode 100644 index 0000000..9bea44d --- /dev/null +++ b/tests/wv/wv-058.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + P + + 2048 + + wv:/chatgroup@server.com + + + + + + diff --git a/tests/wv/wv-059.xml b/tests/wv/wv-059.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-059.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-060.xml b/tests/wv/wv-060.xml new file mode 100644 index 0000000..509664c --- /dev/null +++ b/tests/wv/wv-060.xml @@ -0,0 +1,28 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/chatgroup@there.com + + 5 + + + + + + diff --git a/tests/wv/wv-061.xml b/tests/wv/wv-061.xml new file mode 100644 index 0000000..69b251e --- /dev/null +++ b/tests/wv/wv-061.xml @@ -0,0 +1,69 @@ + + + + + + Inband + im.user.com#48815@server.com + + + + Response + IMApp01#12345@NOK5110 + F + + + + + 0x0000f132 + text/plain + None + 41 + + + + Johnnie + wv:john/chatgroup@there.com + + + + + + + Wicked Vicky + wv:john/chatgroup@there.com + + + + 20010925T1340Z + 600 + + + 0x0000f133 + text/plain + None + 20 + + + + Johnnie + wv:john/chatgroup@there.com + + + + + + + Wicked Vicky + wv:john/chatgroup@there.com + + + + 20010925T1342Z + 600 + + + + + + diff --git a/tests/wv/wv-062.xml b/tests/wv/wv-062.xml new file mode 100644 index 0000000..8add553 --- /dev/null +++ b/tests/wv/wv-062.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + 0x0000f132 + + + + + + diff --git a/tests/wv/wv-063.xml b/tests/wv/wv-063.xml new file mode 100644 index 0000000..e88a54e --- /dev/null +++ b/tests/wv/wv-063.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-064.xml b/tests/wv/wv-064.xml new file mode 100644 index 0000000..5ca7742 --- /dev/null +++ b/tests/wv/wv-064.xml @@ -0,0 +1,60 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + 20010925T1340Z + + 600 + + + + + + + diff --git a/tests/wv/wv-065.xml b/tests/wv/wv-065.xml new file mode 100644 index 0000000..e88a54e --- /dev/null +++ b/tests/wv/wv-065.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-066.xml b/tests/wv/wv-066.xml new file mode 100644 index 0000000..65f67c7 --- /dev/null +++ b/tests/wv/wv-066.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + 0x0000f132 + + + + + + diff --git a/tests/wv/wv-067.xml b/tests/wv/wv-067.xml new file mode 100644 index 0000000..640e389 --- /dev/null +++ b/tests/wv/wv-067.xml @@ -0,0 +1,62 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 41 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + 20010925T1340Z + + 600 + + + Hi guys, just arrived... How is it going? + + + + + + diff --git a/tests/wv/wv-068.xml b/tests/wv/wv-068.xml new file mode 100644 index 0000000..2acf28e --- /dev/null +++ b/tests/wv/wv-068.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12346@NOK5110 + + + + + 0x0000f132 + + + + + + diff --git a/tests/wv/wv-069.xml b/tests/wv/wv-069.xml new file mode 100644 index 0000000..2713454 --- /dev/null +++ b/tests/wv/wv-069.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12346@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-070.xml b/tests/wv/wv-070.xml new file mode 100644 index 0000000..67d2fab --- /dev/null +++ b/tests/wv/wv-070.xml @@ -0,0 +1,48 @@ + + + + + + Inband + im.user.com#48815@server.com + + + + Request + IMApp01#12345@NOK5110 + F + + + + + 0x0000f132 + text/plain + None + 41 + + + + Johnnie + wv:john/chatgroup@there.com + + + + + + + Wicked Vicky + wv:john/chatgroup@there.com + + + + 20010925T1340Z + 600 + + + Hi guys, just arrived... How is it going? + + + + + + \ No newline at end of file diff --git a/tests/wv/wv-071.xml b/tests/wv/wv-071.xml new file mode 100644 index 0000000..235c554 --- /dev/null +++ b/tests/wv/wv-071.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + + + + 0x0000f132 + + + + + + diff --git a/tests/wv/wv-072.xml b/tests/wv/wv-072.xml new file mode 100644 index 0000000..42bf1de --- /dev/null +++ b/tests/wv/wv-072.xml @@ -0,0 +1,68 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + 20010925T1341Z + + + 0x0000f132 + + text/plain + + None + + 41 + + + + + B. Billy + + wv:/happy@hippie.com + + + + + + + + Johnnie + + wv:/happy@hippie.com + + + + + 20010925T1340Z + + 600 + + + + + + + diff --git a/tests/wv/wv-073.xml b/tests/wv/wv-073.xml new file mode 100644 index 0000000..e88a54e --- /dev/null +++ b/tests/wv/wv-073.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-074.xml b/tests/wv/wv-074.xml new file mode 100644 index 0000000..35bfc3c --- /dev/null +++ b/tests/wv/wv-074.xml @@ -0,0 +1,36 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + 0x0000f132 + + + + + B. Billy + + wv:/happy@hippie.com + + + + + + + + + diff --git a/tests/wv/wv-075.xml b/tests/wv/wv-075.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-075.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-076.xml b/tests/wv/wv-076.xml new file mode 100644 index 0000000..655a15b --- /dev/null +++ b/tests/wv/wv-076.xml @@ -0,0 +1,24 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + + + + diff --git a/tests/wv/wv-077.xml b/tests/wv/wv-077.xml new file mode 100644 index 0000000..f51d218 --- /dev/null +++ b/tests/wv/wv-077.xml @@ -0,0 +1,62 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + F + + + wv:he@there.com + + wv:she@there.com + + + Billyboy + + wv:john/chatgroup@there.com + + + wv:/boringlist@server.com + + + + + T + + + wv:matthias@salamander.com + + wv:francisco@don.com + + + WV + + wv:john/chatgroup@there.com + + + wv:/wireless@village.com + + + + + + + + diff --git a/tests/wv/wv-078.xml b/tests/wv/wv-078.xml new file mode 100644 index 0000000..e4a15db --- /dev/null +++ b/tests/wv/wv-078.xml @@ -0,0 +1,44 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + T + + + + + wv:matthias@salamander.com + + + + + + + + wv:matthias@salamander.com + + + + + + + + + + diff --git a/tests/wv/wv-079.xml b/tests/wv/wv-079.xml new file mode 100644 index 0000000..383ac2a --- /dev/null +++ b/tests/wv/wv-079.xml @@ -0,0 +1,30 @@ + + + + + + Outband + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-080.xml b/tests/wv/wv-080.xml new file mode 100644 index 0000000..d550d61 --- /dev/null +++ b/tests/wv/wv-080.xml @@ -0,0 +1,24 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + + + + diff --git a/tests/wv/wv-081.xml b/tests/wv/wv-081.xml new file mode 100644 index 0000000..0588423 --- /dev/null +++ b/tests/wv/wv-081.xml @@ -0,0 +1,36 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + wv:john/My_friends@smith.com + + wv:john/My_family@smith.com + + wv:john/My_colleagues@smith.com + + wv:john/The_WV@smith.com + + wv:john/My_enemies@smith.com + + + + + + diff --git a/tests/wv/wv-082.xml b/tests/wv/wv-082.xml new file mode 100644 index 0000000..36ad58a --- /dev/null +++ b/tests/wv/wv-082.xml @@ -0,0 +1,54 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/My_friends@smith.com + + + + Brainstorm + + wv:bright@dark.com + + + + Randall the Vandal + + wv:randall@fairlane.com + + + + + + DisplayName + + My friends + + + + Default + + F + + + + + + + + diff --git a/tests/wv/wv-083.xml b/tests/wv/wv-083.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-083.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-084.xml b/tests/wv/wv-084.xml new file mode 100644 index 0000000..daaff56 --- /dev/null +++ b/tests/wv/wv-084.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/My_enemies@smith.com + + + + + + diff --git a/tests/wv/wv-085.xml b/tests/wv/wv-085.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-085.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-086.xml b/tests/wv/wv-086.xml new file mode 100644 index 0000000..9a3395e --- /dev/null +++ b/tests/wv/wv-086.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/My_friends@smith.com + + + + + + diff --git a/tests/wv/wv-087.xml b/tests/wv/wv-087.xml new file mode 100644 index 0000000..f43a928 --- /dev/null +++ b/tests/wv/wv-087.xml @@ -0,0 +1,70 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + + + + Brainstrom + + wv:bright@dark.com + + + + Randall the Vandal + + wv:randall@fairlane.com + + + + JLo + + wv:jenny@logic.com + + + + Ex + + wv:ex@wife.com + + + + + + DisplayName + + My friends + + + + Default + + F + + + + + + + + diff --git a/tests/wv/wv-088.xml b/tests/wv/wv-088.xml new file mode 100644 index 0000000..3885751 --- /dev/null +++ b/tests/wv/wv-088.xml @@ -0,0 +1,40 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/My_friends@smith.com + + + + Randall the Vandal + + wv:randall@fairlane.com + + + + JLo + + wv:jenny@logic.com + + + + + + + + diff --git a/tests/wv/wv-089.xml b/tests/wv/wv-089.xml new file mode 100644 index 0000000..4cbed26 --- /dev/null +++ b/tests/wv/wv-089.xml @@ -0,0 +1,44 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + + + + Randall the Vandal + + wv:randall@fairlane.com + + + + JLo + + wv:jenny@logic.com + + + + + + + + diff --git a/tests/wv/wv-090.xml b/tests/wv/wv-090.xml new file mode 100644 index 0000000..524836b --- /dev/null +++ b/tests/wv/wv-090.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/My_friends@smith.com + + + wv:randall@fairlane.com + + wv:jenny@logic.com + + + + + + + diff --git a/tests/wv/wv-091.xml b/tests/wv/wv-091.xml new file mode 100644 index 0000000..83be632 --- /dev/null +++ b/tests/wv/wv-091.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + + + + + + + + diff --git a/tests/wv/wv-092.xml b/tests/wv/wv-092.xml new file mode 100644 index 0000000..e6ec6d6 --- /dev/null +++ b/tests/wv/wv-092.xml @@ -0,0 +1,40 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/My_friends@smith.com + + + + DisplayName + + My enemies + + + + Default + + T + + + + + + + + diff --git a/tests/wv/wv-093.xml b/tests/wv/wv-093.xml new file mode 100644 index 0000000..f05acd7 --- /dev/null +++ b/tests/wv/wv-093.xml @@ -0,0 +1,44 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + + + + DisplayName + + My enemies + + + + Default + + T + + + + + + + + diff --git a/tests/wv/wv-094.xml b/tests/wv/wv-094.xml new file mode 100644 index 0000000..9e003f6 --- /dev/null +++ b/tests/wv/wv-094.xml @@ -0,0 +1,40 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + + + + + + + somebody@nowhere.com + + another_one@nowhere.com + + wv:john/My_friends@smith.com + + wv:john/My_family@smith.com + + T + + + + + + diff --git a/tests/wv/wv-095.xml b/tests/wv/wv-095.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-095.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-096.xml b/tests/wv/wv-096.xml new file mode 100644 index 0000000..7425e3f --- /dev/null +++ b/tests/wv/wv-096.xml @@ -0,0 +1,34 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + somebody@nowhere.com + + another_one@nowhere.com + + wv:john/My_friends@smith.com + + wv:john/My_family@smith.com + + T + + + + + + diff --git a/tests/wv/wv-097.xml b/tests/wv/wv-097.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-097.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-098.xml b/tests/wv/wv-098.xml new file mode 100644 index 0000000..5e0914a --- /dev/null +++ b/tests/wv/wv-098.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + T + + + + + + diff --git a/tests/wv/wv-099.xml b/tests/wv/wv-099.xml new file mode 100644 index 0000000..76d8e0e --- /dev/null +++ b/tests/wv/wv-099.xml @@ -0,0 +1,82 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + + + + + + + + + + + somebody@nowhere.com + + + + + + + + + + + + + + another_one@nowhere.com + + + + + + + + + + wv:john/My_friends@smith.com + + + + + + + + + + wv:john/My_family@smith.com + + + + + + + + + + + + + diff --git a/tests/wv/wv-100.xml b/tests/wv/wv-100.xml new file mode 100644 index 0000000..e339af3 --- /dev/null +++ b/tests/wv/wv-100.xml @@ -0,0 +1,80 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/partygroup@there.com + + + + Name + + Party discussion + + + + Accesstype + + Restricted + + + + PrivateMessaging + + F + + + + Searchable + + T + + + + Topic + + Party + + + + MaxActiveUsers + + 30 + + + + text/plain + + Welcome to WV's party house + + + + T + + + Jonhhie + + wv:thisgroup/group@server.com + + + T + + + + + + diff --git a/tests/wv/wv-101.xml b/tests/wv/wv-101.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-101.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-102.xml b/tests/wv/wv-102.xml new file mode 100644 index 0000000..ad4926c --- /dev/null +++ b/tests/wv/wv-102.xml @@ -0,0 +1,26 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/partygroup@there.com + + + + + + diff --git a/tests/wv/wv-103.xml b/tests/wv/wv-103.xml new file mode 100644 index 0000000..7b87990 --- /dev/null +++ b/tests/wv/wv-103.xml @@ -0,0 +1,32 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + 200 + + Successfully completed. + + + + + + + diff --git a/tests/wv/wv-104.xml b/tests/wv/wv-104.xml new file mode 100644 index 0000000..fd6fe21 --- /dev/null +++ b/tests/wv/wv-104.xml @@ -0,0 +1,30 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + + + + wv:john/partygroup@there.com + + T + + T + + + + + + diff --git a/tests/wv/wv-105.xml b/tests/wv/wv-105.xml new file mode 100644 index 0000000..4c47ea1 --- /dev/null +++ b/tests/wv/wv-105.xml @@ -0,0 +1,64 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Response + + IMApp01#12345@NOK5110 + + F + + + + + + + Johnny + + wv:john/partygroup@there.com + + + + He + + wv:john/partygroup@there.com + + + + She + + wv:john/partygroup@there.com + + + + Francisco + + wv:john/partygroup@there.com + + + + Matthias + + wv:john/partygroup@there.com + + + + + text/plain + + Welcome to WVs party house + + + + + + + diff --git a/tests/wv/wv-106-datetime.xml b/tests/wv/wv-106-datetime.xml new file mode 100644 index 0000000..72ec7f4 --- /dev/null +++ b/tests/wv/wv-106-datetime.xml @@ -0,0 +1,66 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + + 20010925T1340 + + 600 + + + + + + + diff --git a/tests/wv/wv-107-datetime.xml b/tests/wv/wv-107-datetime.xml new file mode 100644 index 0000000..7ab5189 --- /dev/null +++ b/tests/wv/wv-107-datetime.xml @@ -0,0 +1,66 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + + 20010925T134013 + + 600 + + + + + + + diff --git a/tests/wv/wv-108-datetime.xml b/tests/wv/wv-108-datetime.xml new file mode 100644 index 0000000..70e129e --- /dev/null +++ b/tests/wv/wv-108-datetime.xml @@ -0,0 +1,65 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + 20010925T1340Z + + 600 + + + + + + + diff --git a/tests/wv/wv-109-datetime.xml b/tests/wv/wv-109-datetime.xml new file mode 100644 index 0000000..95b3e75 --- /dev/null +++ b/tests/wv/wv-109-datetime.xml @@ -0,0 +1,65 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + 20010925T134013Z + + 600 + + + + + + + diff --git a/tests/wv/wv-110-datetime.xml b/tests/wv/wv-110-datetime.xml new file mode 100644 index 0000000..9e60fec --- /dev/null +++ b/tests/wv/wv-110-datetime.xml @@ -0,0 +1,65 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + 2001-09-25T13:40:13Z + + 600 + + + + + + + diff --git a/tests/wv/wv-111-datetime.xml b/tests/wv/wv-111-datetime.xml new file mode 100644 index 0000000..b9b2abf --- /dev/null +++ b/tests/wv/wv-111-datetime.xml @@ -0,0 +1,66 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + 2001-09-25T13:40:13A + + 600 + + + + + + + diff --git a/tests/wv/wv-112-datetime.xml b/tests/wv/wv-112-datetime.xml new file mode 100644 index 0000000..e6fa88e --- /dev/null +++ b/tests/wv/wv-112-datetime.xml @@ -0,0 +1,66 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + 2001-09-25T13:40:13+01:00 + + 600 + + + + + + + diff --git a/tests/wv/wv-113-datetime.xml b/tests/wv/wv-113-datetime.xml new file mode 100644 index 0000000..eb1b6ad --- /dev/null +++ b/tests/wv/wv-113-datetime.xml @@ -0,0 +1,66 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + 2001-09-25T13:40:13+0100 + + 600 + + + + + + + diff --git a/tests/wv/wv-114-datetime.xml b/tests/wv/wv-114-datetime.xml new file mode 100644 index 0000000..e9afb07 --- /dev/null +++ b/tests/wv/wv-114-datetime.xml @@ -0,0 +1,66 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + 2001-09-25T13:40:13+01 + + 600 + + + + + + + diff --git a/tests/wv/wv-115-datetime.xml b/tests/wv/wv-115-datetime.xml new file mode 100644 index 0000000..ed0eff7 --- /dev/null +++ b/tests/wv/wv-115-datetime.xml @@ -0,0 +1,66 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + 2001-09-25T13:40:13+1 + + 600 + + + + + + + diff --git a/tests/wv/wv-116-datetime.xml b/tests/wv/wv-116-datetime.xml new file mode 100644 index 0000000..f8c06dc --- /dev/null +++ b/tests/wv/wv-116-datetime.xml @@ -0,0 +1,66 @@ + + + + + + Inband + + im.user.com#48815@server.com + + + + + Request + + IMApp01#12345@NOK5110 + + F + + + + + + 0x0000f132 + + text/plain + + None + + 189 + + + + + Johnnie + + wv:john/chatgroup@there.com + + + + + + + + Wicked Vicky + + wv:john/chatgroup@there.com + + + + + + 2001-09-25T13:40:13-05:00 + + 600 + + + + + + + diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 0000000..b2c4315 --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,24 @@ +LINK_DIRECTORIES( ${EXPAT_LIBRARY_DIRS} ) + +INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${EXPAT_INCLUDE_DIRS} ) + +if(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +endif(COMMAND cmake_policy) + +CONFIGURE_FILE( "config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/config.h") + +IF( LIBWBXML_POSIX_GETOPT ) + SET( ATTGETOPT "" ) +ELSE( LIBWBXML_POSIX_GETOPT ) + SET( ATTGETOPT "attgetopt.c" ) +ENDIF( LIBWBXML_POSIX_GETOPT ) + +ADD_EXECUTABLE( wbxml2xml wbxml2xml_tool.c ${ATTGETOPT} ) + TARGET_LINK_LIBRARIES( wbxml2xml wbxml2 ) + INSTALL( TARGETS wbxml2xml DESTINATION ${LIBWBXML_BIN_DIR} ) + +ADD_EXECUTABLE( xml2wbxml xml2wbxml_tool.c ${ATTGETOPT} ) + TARGET_LINK_LIBRARIES( xml2wbxml wbxml2 ) + INSTALL( TARGETS xml2wbxml DESTINATION ${LIBWBXML_BIN_DIR} ) + diff --git a/tools/attgetopt.c b/tools/attgetopt.c new file mode 100644 index 0000000..6f64025 --- /dev/null +++ b/tools/attgetopt.c @@ -0,0 +1,108 @@ +/** + * @file attgetopt.c + * @ingroup wbxml2xml_tool + * @ingroup xml2wbxml_tool + * + * AT&T's public domain implementation of getopt. + * + * From the mod.sources newsgroup, volume 3, issue 58, with modifications + * to bring it up to 21st century C. + */ + +/* Copied from: http://everything2.com/e2node/getopt%2528%2529 + * getopt renamed to wbxml_getopt + */ + +/* getopt.c: + * a public domain implementation of getopt() + * + * The following source code is an adaptation of the public domain getopt() + * implementation presented at the 1985 UNIFORUM conference in Dallas, + * Texas. Slight edits have been made to improve readability and the result + * is released into the public domain like that from which it was derived. + * + */ + +#include +#include + +int optind = 1; +/* useless variable +int optopt; +*/ +char *optarg; + +int +wbxml_getopt(int argc, char **argv, char *opts) +{ + static int sp = 1; + register int c; + register char *cp; + + if (sp == 1) { + + /* If all args are processed, finish */ + if (optind >= argc) { + return EOF; + } + if (argv[optind][0] != '-' || argv[optind][1] == '\0') { + return EOF; + } + + } else if (!strcmp(argv[optind], "--")) { + + /* No more options to be processed after this one */ + optind++; + return EOF; + + } + + /* useless variable: optopt + optopt = c = argv[optind][sp]; + */ + c = argv[optind][sp]; + + /* Check for invalid option */ + if (c == ':' || (cp = strchr(opts, c)) == NULL) { + + fprintf(stderr, + "%s: illegal option -- %c\n", + argv[0], + c); + if (argv[optind][++sp] == '\0') { + optind++; + sp = 1; + } + + return '?'; + } + + /* Does this option require an argument? */ + if (*++cp == ':') { + + /* If so, get argument; if none provided output error */ + if (argv[optind][sp+1] != '\0') { + optarg = &argv[optind++][sp+1]; + } else if (++optind >= argc) { + fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], + c); + sp = 1; + return '?'; + } else { + optarg = argv[optind++]; + } + sp = 1; + + } else { + if (argv[optind][++sp] == '\0') { + sp = 1; + optind++; + } + optarg = NULL; + } + + return c; +} + diff --git a/tools/config.h.cmake b/tools/config.h.cmake new file mode 100644 index 0000000..aa1a488 --- /dev/null +++ b/tools/config.h.cmake @@ -0,0 +1,10 @@ +/* + * Copyright (C) 2008 Michael Bell + */ + +#ifndef WBXML_TOOLS_CONFIG_H +#define WBXML_TOOLS_CONFIG_H + +#cmakedefine FOUND_POSIX_GETOPT + +#endif /* WBXML_TOOLS_CONFIG_H */ diff --git a/tools/getopt.h b/tools/getopt.h new file mode 100644 index 0000000..181d639 --- /dev/null +++ b/tools/getopt.h @@ -0,0 +1,30 @@ +/** + * @file getopt.h + * @ingroup wbxml2xml_tool + * @ingroup xml2wbxml_tool + * + * @brief wbxml_getopt() is just another copy of the getopt implementation of AT&T + */ + +#ifndef WBXML_GETOPT_H +#define WBXML_GETOPT_H + +#include "tools/config.h" + +#ifdef FOUND_POSIX_GETOPT + +#include +#define wbxml_getopt getopt + +#else /* FOUND_POSIX_GETOPT */ + +int wbxml_getopt(int argc, char **argv, char *opts); +extern int optind; +/* useless variable +extern int optopt; +*/ +extern char *optarg; + +#endif /* FOUND_POSIX_GETOPT */ + +#endif diff --git a/tools/wbxml2xml_tool.c b/tools/wbxml2xml_tool.c new file mode 100644 index 0000000..415d46d --- /dev/null +++ b/tools/wbxml2xml_tool.c @@ -0,0 +1,502 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file wbxml2xml_tool.c + * @ingroup wbxml2xml_tool + * + * @author Aymerick Jehanne + * @date 03/02/22 + * + * @brief WBXML to XML Converter Tool + * + */ + +#if !defined ( __SYMBIAN32__ ) +#include +#endif /* ! __SYMBIAN32__ */ + +/* The real libwbxml include is: + * + * #include + * + * We must use a direct reference to enforce the correct include. + */ +#include "../src/wbxml.h" + +#ifdef WBXML_USE_LEAKTRACKER +#include "src/wbxml_mem.h" +#endif + +#include "getopt.h" + +/* + * This sytem include is here instead of the *.c files because + * we want it to be included AFTER 'e32def.h' (in 'wbxml.h') on Symbian. + * If not so, Warnings are displayed ('NULL' : macro redefinition) + */ +#include + + +#define INPUT_BUFFER_SIZE 1000 + +static WBXMLLanguage get_lang(const WB_TINY *lang) +{ +#if defined( WBXML_SUPPORT_WML ) + if (WBXML_STRCMP(lang, "WML10") == 0) + return WBXML_LANG_WML10; + if (WBXML_STRCMP(lang, "WML11") == 0) + return WBXML_LANG_WML11; + if (WBXML_STRCMP(lang, "WML12") == 0) + return WBXML_LANG_WML12; + if (WBXML_STRCMP(lang, "WML13") == 0) + return WBXML_LANG_WML13; +#endif /* WBXML_SUPPORT_WML */ + +#if defined( WBXML_SUPPORT_WTA ) + if (WBXML_STRCMP(lang, "WTA10") == 0) + return WBXML_LANG_WTA10; + if (WBXML_STRCMP(lang, "WTAWML12") == 0) + return WBXML_LANG_WTAWML12; + if (WBXML_STRCMP(lang, "CHANNEL11") == 0) + return WBXML_LANG_CHANNEL11; + if (WBXML_STRCMP(lang, "CHANNEL12") == 0) + return WBXML_LANG_CHANNEL12; +#endif /* WBXML_SUPPORT_WTA */ + +#if defined( WBXML_SUPPORT_SI ) + if (WBXML_STRCMP(lang, "SI10") == 0) + return WBXML_LANG_SI10; +#endif /* WBXML_SUPPORT_SI */ + +#if defined( WBXML_SUPPORT_SL ) + if (WBXML_STRCMP(lang, "SL10") == 0) + return WBXML_LANG_SL10; +#endif /* WBXML_SUPPORT_SL */ + +#if defined( WBXML_SUPPORT_CO ) + if (WBXML_STRCMP(lang, "CO10") == 0) + return WBXML_LANG_CO10; +#endif /* WBXML_SUPPORT_CO */ + +#if defined( WBXML_SUPPORT_PROV ) + if (WBXML_STRCMP(lang, "PROV10") == 0) + return WBXML_LANG_PROV10; +#endif /* WBXML_SUPPORT_PROV */ + +#if defined( WBXML_SUPPORT_EMN ) + if (WBXML_STRCMP(lang, "EMN10") == 0) + return WBXML_LANG_EMN10; +#endif /* WBXML_SUPPORT_EMN */ + +#if defined( WBXML_SUPPORT_DRMREL ) + if (WBXML_STRCMP(lang, "DRMREL10") == 0) + return WBXML_LANG_DRMREL10; +#endif /* WBXML_SUPPORT_DRMREL */ + +#if defined( WBXML_SUPPORT_OTA_SETTINGS ) + if (WBXML_STRCMP(lang, "OTA") == 0) + return WBXML_LANG_OTA_SETTINGS; +#endif /* WBXML_SUPPORT_OTA_SETTINGS */ + +#if defined( WBXML_SUPPORT_SYNCML ) + if (WBXML_STRCMP(lang, "SYNCML10") == 0) + return WBXML_LANG_SYNCML_SYNCML10; + if (WBXML_STRCMP(lang, "DEVINF10") == 0) + return WBXML_LANG_SYNCML_DEVINF10; + if (WBXML_STRCMP(lang, "SYNCML11") == 0) + return WBXML_LANG_SYNCML_SYNCML11; + if (WBXML_STRCMP(lang, "DEVINF11") == 0) + return WBXML_LANG_SYNCML_DEVINF11; + if (WBXML_STRCMP(lang, "METINF11") == 0) + return WBXML_LANG_SYNCML_METINF11; + if (WBXML_STRCMP(lang, "SYNCML12") == 0) + return WBXML_LANG_SYNCML_SYNCML12; + if (WBXML_STRCMP(lang, "DEVINF12") == 0) + return WBXML_LANG_SYNCML_DEVINF12; + if (WBXML_STRCMP(lang, "METINF12") == 0) + return WBXML_LANG_SYNCML_METINF12; + if (WBXML_STRCMP(lang, "DMDDF12") == 0) + return WBXML_LANG_SYNCML_DMDDF12; +#endif /* WBXML_SUPPORT_SYNCML */ + +#if defined( WBXML_SUPPORT_WV ) + if (WBXML_STRCMP(lang, "CSP11") == 0) + return WBXML_LANG_WV_CSP11; + if (WBXML_STRCMP(lang, "CSP12") == 0) + return WBXML_LANG_WV_CSP12; +#endif /* WBXML_SUPPORT_WV */ + +#if defined( WBXML_SUPPORT_AIRSYNC ) + if (WBXML_STRCMP(lang, "AIRSYNC") == 0) + return WBXML_LANG_AIRSYNC; + if (WBXML_STRCMP(lang, "ACTIVESYNC") == 0) + return WBXML_LANG_ACTIVESYNC; +#endif /* WBXML_SUPPORT_AIRSYNC */ + +#if defined( WBXML_SUPPORT_CONML ) + if (WBXML_STRCMP(lang, "CONML") == 0) + return WBXML_LANG_CONML; +#endif /* WBXML_SUPPORT_CONML */ + + return WBXML_LANG_UNKNOWN; +} + + +static WBXMLCharsetMIBEnum get_charset(const WB_TINY *charset) +{ + /* The good old ASCII */ + + if (WBXML_STRCMP(charset, "ASCII") == 0) + return WBXML_CHARSET_US_ASCII; + + /* ISO-8859 character sets */ + + if (WBXML_STRCMP(charset, "ISO-8859-1") == 0) + return WBXML_CHARSET_ISO_8859_1; + if (WBXML_STRCMP(charset, "ISO-8859-2") == 0) + return WBXML_CHARSET_ISO_8859_2; + if (WBXML_STRCMP(charset, "ISO-8859-3") == 0) + return WBXML_CHARSET_ISO_8859_3; + if (WBXML_STRCMP(charset, "ISO-8859-4") == 0) + return WBXML_CHARSET_ISO_8859_4; + if (WBXML_STRCMP(charset, "ISO-8859-5") == 0) + return WBXML_CHARSET_ISO_8859_5; + if (WBXML_STRCMP(charset, "ISO-8859-6") == 0) + return WBXML_CHARSET_ISO_8859_6; + if (WBXML_STRCMP(charset, "ISO-8859-7") == 0) + return WBXML_CHARSET_ISO_8859_7; + if (WBXML_STRCMP(charset, "ISO-8859-8") == 0) + return WBXML_CHARSET_ISO_8859_8; + if (WBXML_STRCMP(charset, "ISO-8859-9") == 0) + return WBXML_CHARSET_ISO_8859_9; + if (WBXML_STRCMP(charset, "ISO-10646-UCS-2") == 0) + return WBXML_CHARSET_ISO_10646_UCS_2; + + /* Chinese character set */ + + if (WBXML_STRCMP(charset, "SHIFT_JIS") == 0) + return WBXML_CHARSET_SHIFT_JIS; + + /* Japanese character set */ + + if (WBXML_STRCMP(charset, "BIG5") == 0) + return WBXML_CHARSET_BIG5; + + /* Unicode character sets */ + + if (WBXML_STRCMP(charset, "UTF-8") == 0) + return WBXML_CHARSET_UTF_8; + if (WBXML_STRCMP(charset, "UTF-16") == 0) + return WBXML_CHARSET_UTF_16; + + return WBXML_CHARSET_UNKNOWN; +} + + +static void help(void) +{ + fprintf(stderr, "wbxml2xml [libwbxml %s] by OpenSync\n", WBXML_LIB_VERSION); + fprintf(stderr, "This library was originally written by Aymerick Jehanne \n"); + fprintf(stderr, "If you use this tool, please send feedbacks to opensync-users@opensync.org\n"); + fprintf(stderr, "http://libwbxml.opensync.org/\n"); +#if defined( HAVE_EXPAT ) + fprintf(stderr, "This tool is linked with Expat (http://expat.sourceforge.net)\n\n"); +#endif /* HAVE_EXPAT */ + fprintf(stderr, "Usage: \n"); + fprintf(stderr, " wbxml2xml -o output.xml input.wbxml\n"); + fprintf(stderr, " wbxml2xml -i 4 -l CSP12 -o output.xml input.wbxml\n\n"); + fprintf(stderr, "Options: \n"); + fprintf(stderr, " -o output.xml : output file\n"); + fprintf(stderr, " -m X (Generation mode - Default: 1) with:\n"); + fprintf(stderr, " 0: Compact Generation\n"); + fprintf(stderr, " 1: Indent Generation\n"); + fprintf(stderr, " 2: Canonical Generation\n"); + fprintf(stderr, " -i X (Indent delta when using mode '1' - Default: 1)\n"); + fprintf(stderr, " -k (Keep Ignorable Whitespaces - Default: FALSE)\n"); + fprintf(stderr, " -l X (Force Language Type of document to parse)\n"); +#if defined( WBXML_SUPPORT_WML ) + fprintf(stderr, " WML10 : WML 1.0\n"); + fprintf(stderr, " WML11 : WML 1.1\n"); + fprintf(stderr, " WML12 : WML 1.2\n"); + fprintf(stderr, " WML13 : WML 1.3\n"); +#endif /* WBXML_SUPPORT_WML */ +#if defined( WBXML_SUPPORT_WTA ) + fprintf(stderr, " WTA10 : WTA 1.0\n"); + fprintf(stderr, " WTAWML12 : WTAWML 1.2\n"); + fprintf(stderr, " CHANNEL11 : CHANNEL 1.1\n"); + fprintf(stderr, " CHANNEL12 : CHANNEL 1.2\n"); +#endif /* WBXML_SUPPORT_WTA */ +#if defined( WBXML_SUPPORT_SI ) + fprintf(stderr, " SI10 : SI 1.0\n"); +#endif /* WBXML_SUPPORT_SI */ +#if defined( WBXML_SUPPORT_SL ) + fprintf(stderr, " SL10 : SL 1.0\n"); +#endif /* WBXML_SUPPORT_SL */ +#if defined( WBXML_SUPPORT_CO ) + fprintf(stderr, " CO10 : CO 1.0\n"); +#endif /* WBXML_SUPPORT_CO */ +#if defined( WBXML_SUPPORT_PROV ) + fprintf(stderr, " PROV10 : PROV 1.0\n"); +#endif /* WBXML_SUPPORT_PROV */ +#if defined( WBXML_SUPPORT_EMN ) + fprintf(stderr, " EMN10 : EMN 1.0\n"); +#endif /* WBXML_SUPPORT_EMN */ +#if defined( WBXML_SUPPORT_DRMREL ) + fprintf(stderr, " DRMREL10 : DRMREL 1.0\n"); +#endif /* WBXML_SUPPORT_DRMREL */ +#if defined( WBXML_SUPPORT_OTA_SETTINGS ) + fprintf(stderr, " OTA : OTA Settings\n"); +#endif /* WBXML_SUPPORT_OTA_SETTINGS */ +#if defined( WBXML_SUPPORT_SYNCML ) + fprintf(stderr, " SYNCML10 : SYNCML 1.0\n"); + fprintf(stderr, " DEVINF10 : DEVINF 1.0\n"); + fprintf(stderr, " SYNCML11 : SYNCML 1.1\n"); + fprintf(stderr, " DEVINF11 : DEVINF 1.1\n"); + fprintf(stderr, " METINF11 : METINF 1.1\n"); + fprintf(stderr, " SYNCML12 : SYNCML 1.2\n"); + fprintf(stderr, " DEVINF12 : DEVINF 1.2\n"); + fprintf(stderr, " METINF12 : METINF 1.2\n"); + fprintf(stderr, " DMDDF12 : DMDDF 1.2\n"); +#endif /* WBXML_SUPPORT_SYNCML */ +#if defined( WBXML_SUPPORT_WV ) + fprintf(stderr, " CSP11 : WV CSP 1.1\n"); + fprintf(stderr, " CSP12 : WV CSP 1.2\n"); +#endif /* WBXML_SUPPORT_WV */ +#if defined( WBXML_SUPPORT_AIRSYNC ) + fprintf(stderr, " AIRSYNC : Microsoft AirSync (SynCE namespaces) \n"); + fprintf(stderr, " ACTIVESYNC : Microsoft ActiveSync (original namespaces)\n"); +#endif /* WBXML_SUPPORT_AIRSYNC */ +#if defined( WBXML_SUPPORT_CONML ) + fprintf(stderr, " CONML : Nokia ConML\n"); +#endif /* WBXML_SUPPORT_CONML */ + fprintf(stderr, " -c X (Set character set if the document does not specify one)\n"); + fprintf(stderr, " ASCII : US ASCII\n"); + fprintf(stderr, " ISO-8859-1 : ISO-8859-1 (Western European)\n"); + fprintf(stderr, " ISO-8859-2 : ISO-8859-2 (Central European)\n"); + fprintf(stderr, " ISO-8859-3 : ISO-8859-3 (South European)\n"); + fprintf(stderr, " ISO-8859-4 : ISO-8859-4 (North European)\n"); + fprintf(stderr, " ISO-8859-5 : ISO-8859-5 (Latin/Cyrillic)\n"); + fprintf(stderr, " ISO-8859-6 : ISO-8859-6 (Latin/Arabic)\n"); + fprintf(stderr, " ISO-8859-7 : ISO-8859-7 (Latin/Greek)\n"); + fprintf(stderr, " ISO-8859-8 : ISO-8859-8 (Latin/Hebrew)\n"); + fprintf(stderr, " ISO-8859-9 : ISO-8859-9 (Latin/Turkish)\n"); + fprintf(stderr, " ISO-10646-UCS-2 : UCS-2\n"); + fprintf(stderr, " SHIFT_JIS : Shift JIS (Japanese character set)\n"); + fprintf(stderr, " BIG5 : Big5 (Chinese character set)\n"); + fprintf(stderr, " UTF-8 : UTF-8\n"); + fprintf(stderr, " UTF-16 : UTF-16\n"); + fprintf(stderr, "\nNote: '-' can be used to mean stdin on input or stdout on output\n\n"); +} + + +WB_LONG main(WB_LONG argc, WB_TINY **argv) +{ + WB_UTINY *wbxml = NULL, *output = NULL, *xml = NULL; + FILE *input_file = NULL, *output_file = NULL; + WB_LONG count = 0, wbxml_len = 0, total = 0; + WB_ULONG xml_len = 0; + WB_TINY opt; + WBXMLError ret = WBXML_OK; + WB_UTINY input_buffer[INPUT_BUFFER_SIZE + 1]; + WBXMLConvWBXML2XML *conv = NULL; + + ret = wbxml_conv_wbxml2xml_create(&conv); + if (ret != WBXML_OK) + { + fprintf(stderr, "wbxml2xml failed: %s\n", wbxml_errors_string(ret)); + goto clean_up; + } + + while ((opt = (WB_TINY) wbxml_getopt(argc, argv, "kh?o:m:i:l:c:")) != EOF) + { + switch (opt) { + case 'k': + wbxml_conv_wbxml2xml_enable_preserve_whitespaces(conv); + break; + case 'i': + wbxml_conv_wbxml2xml_set_indent(conv, (WB_TINY) atoi((const WB_TINY*)optarg)); + break; + case 'l': + wbxml_conv_wbxml2xml_set_language(conv, get_lang((const WB_TINY*)optarg)); + break; + case 'c': + wbxml_conv_wbxml2xml_set_charset(conv, get_charset((const WB_TINY*)optarg)); + break; + case 'm': + switch (atoi((const WB_TINY*)optarg)) { + case 0: + wbxml_conv_wbxml2xml_set_gen_type(conv, WBXML_GEN_XML_COMPACT); + break; + case 1: + wbxml_conv_wbxml2xml_set_gen_type(conv, WBXML_GEN_XML_INDENT); + break; + case 2: + wbxml_conv_wbxml2xml_set_gen_type(conv, WBXML_GEN_XML_CANONICAL); + break; + default: + wbxml_conv_wbxml2xml_set_gen_type(conv, WBXML_GEN_XML_INDENT); + } + break; + case 'o': + output = (WB_UTINY*) optarg; + break; + case 'h': + case '?': + default: + help(); + return 0; + } + } + + if (optind >= argc) { + fprintf(stderr, "Missing arguments\n"); + help(); + return 0; + } + +#ifdef WBXML_USE_LEAKTRACKER + lt_init_mem(); + lt_log_open_file("wbxml2xml.log"); + lt_log(0, "\n***************************\n Converting file: %s", argv[optind]); +#endif + + /********************************** + * Read the WBXML Document + */ + + if (WBXML_STRCMP(argv[optind], "-") == 0) { + input_file = stdin; + } else { + /* Open WBXML document */ + input_file = fopen(argv[optind], "rb"); + if (input_file == NULL) { + fprintf(stderr, "Failed to open %s\n", argv[optind]); + goto clean_up; + } + } + + /* Read WBXML document */ + while(!feof(input_file)) { + count = fread(input_buffer, sizeof(WB_UTINY), INPUT_BUFFER_SIZE, input_file); + if (ferror(input_file)) { + fprintf(stderr, "Error while reading from file %s\n", argv[optind]); + if (input_file != stdin) + fclose(input_file); + if (wbxml != NULL) +#ifdef WBXML_USE_LEAKTRACKER + wbxml_free(wbxml); +#else + free(wbxml); +#endif + goto clean_up; + } + + total += count; +#ifdef WBXML_USE_LEAKTRACKER + wbxml = wbxml_realloc(wbxml, total); +#else + wbxml = realloc(wbxml, total); +#endif + if (wbxml == NULL) { + fprintf(stderr, "Not enought memory\n"); + if (input_file != stdin) + fclose(input_file); + if (wbxml != NULL) +#ifdef WBXML_USE_LEAKTRACKER + wbxml_free(wbxml); +#else + free(wbxml); +#endif + goto clean_up; + } + + memcpy(wbxml + wbxml_len, input_buffer, count); + wbxml_len += count; + } + + if (input_file != stdin) + fclose(input_file); + + /* Convert WBXML document */ + ret = wbxml_conv_wbxml2xml_run(conv, wbxml, wbxml_len, &xml, &xml_len); + if (ret != WBXML_OK) { + fprintf(stderr, "wbxml2xml failed: %s\n", wbxml_errors_string(ret)); + } + else { + /* fprintf(stderr, "wbxml2xml succeded: \n%s\n", xml); */ + fprintf(stderr, "wbxml2xml succeded\n"); + + if (output != NULL) { + if (WBXML_STRCMP(output, "-") == 0) { + output_file = stdout; + } else { + /* Open Output File */ + output_file = fopen((const WB_TINY*) output, "w"); + } + + if (output_file == NULL) { + fprintf(stderr, "Failed to open output file: %s\n", output); + } + + /* Write to Output File */ + if (fwrite(xml, sizeof(WB_UTINY), xml_len, output_file) < xml_len) + fprintf(stderr, "Error while writing to file: %s\n", output); + /* + else + fprintf(stderr, "Written %u bytes to file: %s\n", xml_len, output); + */ + + if (output_file != stdout) + fclose(output_file); + } + + /* Clean-up */ +#ifdef WBXML_USE_LEAKTRACKER + wbxml_free(xml); +#else + free(xml); +#endif + } + +#ifdef WBXML_USE_LEAKTRACKER + wbxml_free(wbxml); +#else + free(wbxml); +#endif + +clean_up: + + if (conv) + wbxml_conv_wbxml2xml_destroy(conv); + +#ifdef WBXML_USE_LEAKTRACKER + lt_check_leaks(); + lt_shutdown_mem(); + lt_log_close_file(); +#endif + + return ret; +} diff --git a/tools/xml2wbxml_tool.c b/tools/xml2wbxml_tool.c new file mode 100644 index 0000000..4c0b646 --- /dev/null +++ b/tools/xml2wbxml_tool.c @@ -0,0 +1,280 @@ +/* + * libwbxml, the WBXML Library. + * Copyright (C) 2002-2008 Aymerick Jehanne + * Copyright (C) 2011 Michael Bell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt + * + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file xml2wbxml_tool.c + * @ingroup xml2wbxml_tool + * + * @author Aymerick Jehanne + * @date 03/03/11 + * + * @brief XML to WBXML Converter Tool + * + */ + +#if !defined ( __SYMBIAN32__ ) +#include +#endif /* ! __SYMBIAN32__ */ + +/* The real libwbxml include is: + * + * #include + * + * We must use a direct reference to enforce the correct include. + */ +#include "../src/wbxml.h" + +#ifdef WBXML_USE_LEAKTRACKER +#include "src/wbxml_mem.h" +#endif + +#include "getopt.h" + +/* + * This sytem include is here instead of the *.c files because + * we want it to be included AFTER 'e32def.h' (in 'wbxml.h') on Symbian. + * If not so, Warnings are displayed ('NULL' : macro redefinition) + */ +#include + + +#define INPUT_BUFFER_SIZE 1000 + + +static WBXMLVersion get_version(const WB_TINY *lang) +{ + if (WBXML_STRCMP(lang, "1.0") == 0) + return WBXML_VERSION_10; + if (WBXML_STRCMP(lang, "1.1") == 0) + return WBXML_VERSION_11; + if (WBXML_STRCMP(lang, "1.2") == 0) + return WBXML_VERSION_12; + if (WBXML_STRCMP(lang, "1.3") == 0) + return WBXML_VERSION_13; + + return WBXML_VERSION_UNKNOWN; +} + + +static void help(void) { + fprintf(stderr, "xml2wbxml [libwbxml %s] by OpenSync\n", WBXML_LIB_VERSION); + fprintf(stderr, "This library was originally written by Aymerick Jehanne \n"); + fprintf(stderr, "If you use this tool, please send feedbacks to opensync-users@opensync.org\n"); + fprintf(stderr, "http://libwbxml.opensync.org/\n"); +#if defined( HAVE_EXPAT ) + fprintf(stderr, "This tool is linked with Expat (http://expat.sourceforge.net)\n\n"); +#endif /* HAVE_EXPAT */ + fprintf(stderr, "Usage: \n"); + fprintf(stderr, " xml2wbxml -o output.wbxml input.xml\n"); + fprintf(stderr, " xml2wbxml -k -n -v 1.1 -o output.wbxml input.xml\n\n"); + fprintf(stderr, "Options: \n"); + fprintf(stderr, " -o output.wbxml : output file\n"); + fprintf(stderr, " -k : keep ignorable whitespaces (Default: ignore)\n"); + fprintf(stderr, " -n : do NOT generate String Table (Default: generate)\n"); + fprintf(stderr, " -v X (WBXML Version of output document)\n"); + fprintf(stderr, " 1.0 : WBXML 1.0\n"); + fprintf(stderr, " 1.1 : WBXML 1.1\n"); + fprintf(stderr, " 1.2 : WBXML 1.2\n"); + fprintf(stderr, " 1.3 : WBXML 1.3\n"); + fprintf(stderr, " -a : anonymous format\n"); + fprintf(stderr, " do NOT include any format information (e.g. public ID or DTD)\n"); + fprintf(stderr, "\nNote: '-' can be used to mean stdin on input or stdout on output\n\n"); +} + + +WB_LONG main(WB_LONG argc, WB_TINY **argv) +{ + WB_UTINY *wbxml = NULL, *output = NULL, *xml = NULL; + FILE *input_file = NULL, *output_file = NULL; + WB_ULONG wbxml_len = 0; + WB_LONG count = 0, xml_len = 0, total = 0; + WB_TINY opt; + WBXMLError ret = WBXML_OK; + WB_UTINY input_buffer[INPUT_BUFFER_SIZE + 1]; + WBXMLConvXML2WBXML *conv = NULL; + + ret = wbxml_conv_xml2wbxml_create(&conv); + if (ret != WBXML_OK) + { + fprintf(stderr, "xml2wbxml failed: %s\n", wbxml_errors_string(ret)); + goto clean_up; + } + + + while ((opt = (WB_TINY) wbxml_getopt(argc, argv, "nkah?o:v:")) != EOF) + { + switch (opt) { + case 'v': + wbxml_conv_xml2wbxml_set_version(conv, get_version((const WB_TINY*)optarg)); + break; + case 'n': + wbxml_conv_xml2wbxml_disable_string_table(conv); + break; + case 'k': + wbxml_conv_xml2wbxml_enable_preserve_whitespaces(conv); + break; + case 'a': + wbxml_conv_xml2wbxml_disable_public_id(conv); + break; + case 'o': + output = (WB_UTINY*) optarg; + break; + case 'h': + case '?': + default: + help(); + return 0; + } + } + + if (optind >= argc) { + fprintf(stderr, "Missing arguments\n"); + help(); + return 0; + } + +#ifdef WBXML_USE_LEAKTRACKER + lt_init_mem(); + lt_log_open_file("xml2wbxml.log"); + lt_log(0, "\n***************************\n Converting file: %s", argv[optind]); +#endif + + /********************************** + * Read the XML Document + */ + + if (WBXML_STRCMP(argv[optind], "-") == 0) { + input_file = stdin; + } else { + /* Open XML document */ + input_file = fopen(argv[optind], "r"); + if (input_file == NULL) { + printf("Failed to open %s\n", argv[optind]); + goto clean_up; + } + } + + /* Read XML document */ + while(!feof(input_file)) { + count = fread(input_buffer, sizeof(WB_UTINY), INPUT_BUFFER_SIZE, input_file); + if (ferror(input_file)) { + fprintf(stderr, "Error while reading from file %s\n", argv[1]); + if (input_file != stdin) + fclose(input_file); + if (xml != NULL) +#ifdef WBXML_USE_LEAKTRACKER + wbxml_free(xml); +#else + free(xml); +#endif + goto clean_up; + } + + total += count; +#ifdef WBXML_USE_LEAKTRACKER + xml = wbxml_realloc(xml, total + 1); +#else + xml = realloc(xml, total + 1); +#endif + if (xml == NULL) { + fprintf(stderr, "Not enought memory\n"); + if (input_file != stdin) + fclose(input_file); + goto clean_up; + } + + memcpy(xml + xml_len, input_buffer, count); + xml_len += count; + } + + if (input_file != stdin) + fclose(input_file); + + xml[xml_len] = '\0'; + + /* Convert XML document */ + ret = wbxml_conv_xml2wbxml_run(conv, xml, xml_len, &wbxml, &wbxml_len); + if (ret != WBXML_OK) { + fprintf(stderr, "xml2wbxml failed: %s\n", wbxml_errors_string(ret)); + } + else { + fprintf(stderr, "xml2wbxml succeded\n"); + + if (output != NULL) { + if (WBXML_STRCMP(output, "-") == 0) { + output_file = stdout; + } + else { + /* Open Output File */ + output_file = fopen((const WB_TINY*) output, "wb"); + } + + if (output_file == NULL) { + fprintf(stderr, "Failed to open output file: %s\n", output); + } + else { + /* Write to Output File */ + if (fwrite(wbxml, sizeof(WB_UTINY), wbxml_len, output_file) < wbxml_len) + fprintf(stderr, "Error while writing to file: %s\n", output); + /* + else + fprintf(stderr, "Written %u bytes to file: %s\n", wbxml_len, output); + */ + + if (output_file != stdout) + fclose(output_file); + } + } + + /* Clean-up */ + if (wbxml != NULL) +#ifdef WBXML_USE_LEAKTRACKER + wbxml_free(wbxml); +#else + free(wbxml); +#endif + } + + if (xml != NULL) +#ifdef WBXML_USE_LEAKTRACKER + wbxml_free(xml); +#else + free(xml); +#endif + +clean_up: + + if (conv != NULL) + wbxml_conv_xml2wbxml_destroy(conv); + +#ifdef WBXML_USE_LEAKTRACKER + lt_check_leaks(); + lt_shutdown_mem(); + lt_log_close_file(); +#endif + + return ret; +} diff --git a/wbxml2.spec.in b/wbxml2.spec.in new file mode 100644 index 0000000..29c0acc --- /dev/null +++ b/wbxml2.spec.in @@ -0,0 +1,87 @@ +%define name @PACKAGE@ +%define ver @VERSION@ +%define RELEASE @RELEASE@ +%define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} +%define prefix /usr + +Summary: WBXML parser and compiler library +Summary(ca_ES): llibreria WBXML amb parser i compilador +Summary(es_ES): libreria WBXML con parser y compilador +Name: %name +Version: %ver +Release: %rel +Copyright: LGPL +Vendor: Aymerick Jéhanne +URL: http://libwbxml.aymerick.com/ + +Packager: Pau Aliagas +Group: Development/Libraries +Source: %{ver}/%{name}-%{ver}.tar.gz + +BuildRoot: %{_tmppath}/%{name}-%{ver}-root +Requires: expat >= 1.95.4 +BuildRequires: expat-devel >= 1.95.4 +AutoReqProv: yes +Provides: wbxml2 + +%description +wbxml2 is a library that includes a WBXML parser and a WBXML compiler. +Unlike wbxml, it does not depend on libxml2 but on expat, making it faster and more portable. + +%description -l ca_ES +wbxml2 és una lliberia que inclou un parser i un compilador WBXML. +A diferència de wbxml, no depén de libxml2, fent-la més ràpida i portable. + +%description -l es_ES +wbxml2 es una liberia que incluye un parser y un compilador WBXML. +A diferencia de wbxml, no depende de libxml2, haciéndola más rápida y portable. + +%prep +%setup +# CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" libtoolize && aclocal && autoheader && automake --add-missing && autoconf && ./configure --prefix=%{prefix} +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --includedir=%{prefix}/include/%{name} + + +%build +# Setup for parallel builds +numprocs=`egrep -c ^cpu[0-9]+ /proc/stat || :` +if [ "$numprocs" = "0" ]; then + numprocs=1 +fi +make -j$numprocs + +%install + +rm -rf $RPM_BUILD_ROOT +rm -rf $RPM_BUILD_DIR/file.list.wbxml + +make install-strip DESTDIR=$RPM_BUILD_ROOT + +# Ensure that all directories exist +cd $RPM_BUILD_ROOT + +# Install include files found in different subdirs (hack) +# SBD=$RPM_BUILD_DIR/%{name}-%{ver} +# install -d ./%{prefix}/include +# install -m644 $SBD/ince/*.h $SBD/inci/*.h ./%{prefix}/include + +# list all files in the distribution +find . -type d | sed '1,2d;s,^\.,\%attr(-\,root\,root) \%dir ,' > $RPM_BUILD_DIR/file.list.wbxml +find . -type f | sed 's,^\.,\%attr(-\,root\,root) ,' >> $RPM_BUILD_DIR/file.list.wbxml +find . -type l | sed 's,^\.,\%attr(-\,root\,root) ,' >> $RPM_BUILD_DIR/file.list.wbxml + +%clean +rm -rf $RPM_BUILD_ROOT +rm -rf $RPM_BUILD_DIR/%{name}-%{ver} +rm -rf $RPM_BUILD_DIR/file.list.wbxml + + +%files -f ../file.list.wbxml + +%changelog + +* Wed Mar 19 2003 Pau Aliagas +- spec number 0.7.1 +- install header files in their own directory +- include new documentation +- first rpm release diff --git a/win32/expat/COPYING.txt b/win32/expat/COPYING.txt new file mode 100644 index 0000000..e3ad54e --- /dev/null +++ b/win32/expat/COPYING.txt @@ -0,0 +1,22 @@ +Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + and Clark Cooper +Copyright (c) 2001, 2002 Expat maintainers. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/win32/expat/README.txt b/win32/expat/README.txt new file mode 100644 index 0000000..3bab5a0 --- /dev/null +++ b/win32/expat/README.txt @@ -0,0 +1,112 @@ + + Expat, Release 1.95.6 + +This is Expat, a C library for parsing XML, written by James Clark. +Expat is a stream-oriented XML parser. This means that you register +handlers with the parser before starting the parse. These handlers +are called when the parser discovers the associated structures in the +document being parsed. A start tag is an example of the kind of +structures for which you may register handlers. + +Windows users should use the expat_win32bin package, which includes +both precompiled libraries and executalbes, and source code for +developers. + +Expat is free software. You may copy, distribute, and modify it under +the terms of the License contained in the file COPYING distributed +with this package. This license is the same as the MIT/X Consortium +license. + +Versions of Expat that have an odd minor version (the middle number in +the release above), are development releases and should be considered +as beta software. Releases with even minor version numbers are +intended to be production grade software. + +If you are building Expat from a check-out from the CVS repository, +you need to run a script that generates the configure script using the +GNU autoconf and libtool tools. To do this, you need to have +autoconf 2.52 or newer and libtool 1.4 or newer. Run the script like +this: + + ./buildconf.sh + +Once this has been done, follow the same instructions as for building +from a source distribution. + +To build Expat from a source distribution, you first run the +configuration shell script in the top level distribution directory: + + ./configure + +There are many options which you may provide to configure (which you +can discover by running configure with the --help option). But the +one of most interest is the one that sets the installation directory. +By default, the configure script will set things up to install +libexpat into /usr/local/lib, expat.h into /usr/local/include, and +xmlwf into /usr/local/bin. If, for example, you'd prefer to install +into /home/me/mystuff/lib, /home/me/mystuff/include, and +/home/me/mystuff/bin, you can tell configure about that with: + + ./configure --prefix=/home/me/mystuff + +After running the configure script, the "make" command will build +things and "make install" will install things into their proper +location. Note that you need to have write permission into the +directories into which things will be installed. + +If you are interested in building Expat to provide document +information in UTF-16 rather than the default UTF-8, following these +instructions: + + 1. For UTF-16 output as unsigned short (and version/error + strings as char), run: + + ./configure CPPFLAGS=-DXML_UNICODE + + For UTF-16 output as wchar_t (incl. version/error strings), + run: + + ./configure CFLAGS="-g -O2 -fshort-wchar" \ + CPPFLAGS=-DXML_UNICODE_WCHAR_T + + 2. Edit the MakeFile, changing: + + LIBRARY = libexpat.la + + to: + + LIBRARY = libexpatw.la + + (Note the additional "w" in the library name.) + + 3. Run "make buildlib" (which builds the library only). + + 4. Run "make installlib" (which installs the library only). + +Note for Solaris users: The "ar" command is usually located in +"/usr/ccs/bin", which is not in the default PATH. You will need to +add this to your path for the "make" command, and probably also switch +to GNU make (the "make" found in /usr/ccs/bin does not seem to work +properly -- appearantly it does not understand .PHONY directives). If +you're using ksh or bash, use this command to build: + + PATH=/usr/ccs/bin:$PATH make + +When using Expat with a project using autoconf for configuration, you +can use the probing macro in conftools/expat.m4 to determine how to +include Expat. See the comments at the top of that file for more +information. + +A reference manual is available in the file doc/reference.html in this +distribution. + +The homepage for this project is http://www.libexpat.org/. There +are links there to connect you to the bug reports page. If you need +to report a bug when you don't have access to a browser, you may also +send a bug report by email to expat-bugs@mail.libexpat.org. + +Discussion related to the direction of future expat development takes +place on expat-discuss@mail.libexpat.org. Archives of this list and +other Expat-related lists may be found at: + + http://mail.libexpat.org/mailman-21/listinfo/ diff --git a/win32/expat/expat.h b/win32/expat/expat.h new file mode 100644 index 0000000..0b70302 --- /dev/null +++ b/win32/expat/expat.h @@ -0,0 +1,926 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef XmlParse_INCLUDED +#define XmlParse_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include + +#ifndef XMLPARSEAPI +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#ifdef XML_STATIC +#define XMLPARSEAPI(type) type __cdecl +#else +#define XMLPARSEAPI(type) __declspec(dllimport) type __cdecl +#endif +#else +#define XMLPARSEAPI(type) type +#endif +#endif /* not defined XMLPARSEAPI */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (*XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (*XML_AttlistDeclHandler) (void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (*XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + When a namespace is not declared, the name and prefix will be + passed through without expansion. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (*XML_StartElementHandler)(void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (*XML_EndElementHandler)(void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (*XML_CharacterDataHandler)(void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (*XML_ProcessingInstructionHandler)(void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data); + +typedef void (*XML_StartCdataSectionHandler)(void *userData); +typedef void (*XML_EndCdataSectionHandler)(void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (*XML_DefaultHandler)(void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (*XML_StartDoctypeDeclHandler)(void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (*XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (*XML_EntityDeclHandler) (void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (*XML_UnparsedEntityDeclHandler)(void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (*XML_NotationDeclHandler)(void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (*XML_StartNamespaceDeclHandler)(void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (*XML_EndNamespaceDeclHandler)(void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (*XML_NotStandaloneHandler)(void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (*XML_SkippedEntityHandler)(void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (*convert)(void *data, const char *s); + void (*release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + The XML_Status enum gives the possible return values for the + XML_Parse and XML_ParseBuffer functions. Though the return values + for these functions has always been described as a Boolean value, + the implementation, at least for the 1.95.x series, has always + returned exactly one of these values. The preprocessor #defines + are included so this stanza can be added to code that still needs + to support older versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1 +#define XML_STATUS_OK XML_STATUS_OK +}; + +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of + the first of the sequence of characters that generated the event. + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(long) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 1 +#define XML_MINOR_VERSION 95 +#define XML_MICRO_VERSION 6 + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlParse_INCLUDED */ diff --git a/win32/expat/libexpat.dll b/win32/expat/libexpat.dll new file mode 100644 index 0000000..13bc7ee Binary files /dev/null and b/win32/expat/libexpat.dll differ diff --git a/win32/expat/libexpat.lib b/win32/expat/libexpat.lib new file mode 100644 index 0000000..f860cb1 Binary files /dev/null and b/win32/expat/libexpat.lib differ diff --git a/win32/leaktrack/COPYING.txt b/win32/leaktrack/COPYING.txt new file mode 100644 index 0000000..8d51b57 --- /dev/null +++ b/win32/leaktrack/COPYING.txt @@ -0,0 +1,32 @@ +Copyright (c) 1998 WAPIT OY LTD. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. All advertising materials mentioning features or use of this software +must display the following acknowledgement: This product includes software +developed by WAPIT OY LTD. + +4. The name of the author may not be used to endorse or promote products +derived from this software without specific prior written permission. + + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/win32/leaktrack/leaktrack.dll b/win32/leaktrack/leaktrack.dll new file mode 100644 index 0000000..0561bd9 Binary files /dev/null and b/win32/leaktrack/leaktrack.dll differ diff --git a/win32/leaktrack/leaktrack.h b/win32/leaktrack/leaktrack.h new file mode 100644 index 0000000..07183b7 --- /dev/null +++ b/win32/leaktrack/leaktrack.h @@ -0,0 +1,157 @@ +/* + * Leaktrack, a Memory Leack Tracker. + * Copyright (C) 2002-2008 Aymerick Jehanne + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * GPL v2: http://www.gnu.org/licenses/gpl.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file leaktrack.h + * @ingroup leaktrack + * + * @brief This is a simple malloc()-wrapper. It does not return NULLs but + * instead panics. + * + * @note We have two wrappers. One that just checks for allocation failures and + * panics if they happen and one that tries to find allocation problems, + * such as using an area after it has been freed. + * Use of native or check wrapper can be modified in config.h + * + * @warning Do NOT use check or native wrapper directly. Instead use this macros: + * - lt_init_mem() + * - lt_shutdown_mem() + * - lt_malloc() + * - lt_free() + * - lt_realloc() + * - lt_strdup() + * + * @note Code adapted from Kannel project (http://www.kannel.org/) + */ + +#ifndef LEAKTRACK_H +#define LEAKTRACK_H + +#include +#include + + +/* For DLL exported functions */ +#ifdef WIN32 +#define LT_DECLARE(type) __declspec(dllexport) type __stdcall +#define LT_DECLARE_NONSTD(type) __declspec(dllexport) type +#else +#define LT_DECLARE(type) type +#define LT_DECLARE_NONSTD(type) type +#endif /* WIN32 */ + + +/* Define one of these depending on which malloc wrapper you want to use. */ +/* #define LEAKTRACK_LEAKTRACK_USE_MEM_NATIVE 1 */ +/* #define LEAKTRACK_USE_MEM_CHECK 1 */ +#define LEAKTRACK_USE_MEM_SLOW 1 + +/* Define if your compiler supports the __func__ magic symbol. This is part of C99. */ +#undef HAVE___FUNC__ + +/* Define if your compiler supports the __FUNCTION__ magic symbol. */ +#undef HAVE___FUNCTION__ + +/* Make sure __func__ does something useful. */ +#if defined(HAVE___FUNC__) + /* Nothing to do. Life is so wonderful. */ +#elif defined(HAVE___FUNCTION__) + #define __func__ __FUNCTION__ +#else + #define __func__ "unknown" +#endif + + +/* Native Functions */ +LT_DECLARE(void *) lt_native_malloc(size_t size); +LT_DECLARE(void *) lt_native_realloc(void *ptr, size_t size); +LT_DECLARE(void) lt_native_free(void *ptr); +LT_DECLARE(char *) lt_native_strdup(const char *str); + +/* Check Functions */ +LT_DECLARE(void) lt_check_init_mem(int slow_flag); +LT_DECLARE(void) lt_check_shutdown(void); +LT_DECLARE(void *) lt_check_malloc(size_t size, const char *filename, long line, const char *function); +LT_DECLARE(void *) lt_check_realloc(void *p, size_t size, const char *filename, long line, const char *function); +LT_DECLARE(void) lt_check_free(void *p, const char *filename, long line, const char *function); +LT_DECLARE(char *) lt_check_strdup(const char *str, const char *filename, long line, const char *function); +LT_DECLARE(void *) lt_check_claim_area(void *p, const char *filename, long line, const char *function); +LT_DECLARE(void) lt_check_check_leaks(void); +LT_DECLARE(int) lt_check_is_allocated(void *p); +LT_DECLARE(long) lt_check_area_size(void *p); + +/* "slow" == "checking" with a small variation */ +#if LEAKTRACK_USE_MEM_SLOW +#define LEAKTRACK_USE_MEM_CHECK 1 +#endif + + +#if LEAKTRACK_USE_MEM_NATIVE + +/* Native wrapper */ +#define lt_init_mem() +#define lt_check_leaks() +#define lt_malloc(size) (lt_native_malloc(size)) +#define lt_realloc(ptr, size) (lt_native_realloc(ptr, size)) +#define lt_free(ptr) (lt_native_free(ptr)) +#define lt_strdup(str) (lt_native_strdup(str)) +#define lt_assert_allocated(ptr, file, line, function) +#define lt_claim_area(ptr) (ptr) +#define lt_claim_area_for(ptr, file, line, func) (ptr) +#define lt_shutdown_mem() + +#elif LEAKTRACK_USE_MEM_CHECK + +/* Check wrapper */ +#ifdef LEAKTRACK_USE_MEM_SLOW +#define lt_init_mem() (lt_check_init_mem(1)) +#else +#define lt_init_mem() (lt_check_init_mem(0)) +#endif + +#define lt_check_leaks() (lt_check_check_leaks()) +#define lt_malloc(size) (lt_check_malloc(size, __FILE__, __LINE__, __func__)) +#define lt_realloc(ptr, size) (lt_check_realloc(ptr, size, __FILE__, __LINE__, __func__)) +#define lt_free(ptr) (lt_check_free(ptr, __FILE__, __LINE__, __func__)) +#define lt_strdup(str) (lt_check_strdup(str, __FILE__, __LINE__, __func__)) +#define lt_assert_allocated(ptr, file, line, function) (lt_assert_place(lt_check_is_allocated(ptr), file, line, function)) +#define lt_claim_area(ptr) (lt_check_claim_area(ptr, __FILE__, __LINE__, __func__)) +#define lt_claim_area_for(ptr, file, line, func) (lt_check_claim_area(ptr, file, line, func)) +#define lt_shutdown_mem() (lt_check_shutdown()) + +#else + +/* Unknown wrapper */ +#error "Unknown malloc wrapper." + +#endif + + +/* Make sure no-one uses the unwrapped functions by mistake */ +#define malloc(n) do_not_call_malloc_directly +#define calloc(a, b) do_not_use_calloc +#define realloc(p, n) do_not_call_realloc_directly +#define free(p) do_not_call_free_directly + +#endif diff --git a/win32/leaktrack/leaktrack.lib b/win32/leaktrack/leaktrack.lib new file mode 100644 index 0000000..9f9fd8b Binary files /dev/null and b/win32/leaktrack/leaktrack.lib differ diff --git a/win32/leaktrack/lt_log.h b/win32/leaktrack/lt_log.h new file mode 100644 index 0000000..39d6523 --- /dev/null +++ b/win32/leaktrack/lt_log.h @@ -0,0 +1,55 @@ +/* + * Leaktrack, a Memory Leack Tracker. + * Copyright (C) 2002-2008 Aymerick Jehanne + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * GPL v2: http://www.gnu.org/licenses/gpl.txt + * + * Contact: aymerick@jehanne.org + * Home: http://libwbxml.aymerick.com + */ + +/** + * @file lt_log.h + * @ingroup leaktrack + * + * @brief Log Functions + * + * @note Code adapted from Kannel project (http://www.kannel.org/) + */ + +#ifndef LEAKTRACK_LOG_H +#define LEAKTRACK_LOG_H + +/** + * @brief Open the log file + * @param filename The logfile name + */ +LT_DECLARE(void) lt_log_open_file(char *filename); + +/** + * @brief Logging function + * @param e If different from 0, try to resolve a system error + * @param fmt The log text (in printf style) + */ +LT_DECLARE_NONSTD(void) lt_log(int e, const char *fmt, ...); + +/** + * @brief Close the log file + */ +LT_DECLARE(void) lt_log_close_file(void); + +#endif \ No newline at end of file diff --git a/win32/libwbxml.dsw b/win32/libwbxml.dsw new file mode 100644 index 0000000..3924fac --- /dev/null +++ b/win32/libwbxml.dsw @@ -0,0 +1,59 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "libwbxml2"=.\libwbxml2\libwbxml2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "wbxml2xml"=.\wbxml2xml\wbxml2xml.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libwbxml2 + End Project Dependency +}}} + +############################################################################### + +Project: "xml2wbxml"=.\xml2wbxml\xml2wbxml.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libwbxml2 + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/win32/libwbxml2/libwbxml2.dsp b/win32/libwbxml2/libwbxml2.dsp new file mode 100644 index 0000000..7216ffe --- /dev/null +++ b/win32/libwbxml2/libwbxml2.dsp @@ -0,0 +1,239 @@ +# Microsoft Developer Studio Project File - Name="libwbxml2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=libwbxml2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libwbxml2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libwbxml2.mak" CFG="libwbxml2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libwbxml2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libwbxml2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libwbxml2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBWBXML2_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../expat" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBWBXML2_EXPORTS" /D "WBXML_SUPPORT_WML" /D "WBXML_SUPPORT_WTA" /D "WBXML_SUPPORT_SI" /D "WBXML_SUPPORT_SL" /D "WBXML_SUPPORT_CO" /D "WBXML_SUPPORT_PROV" /D "WBXML_SUPPORT_EMN" /D "WBXML_SUPPORT_DRMREL" /D "WBXML_SUPPORT_OTA_SETTINGS" /D "WBXML_SUPPORT_SYNCML" /D "WBXML_SUPPORT_WV" /D "WBXML_SUPPORT_AIRSYNC" /D "WBXML_ENCODER_USE_STRTBL" /D "HAVE_EXPAT" /D "WBXML_WRAPPERS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libexpat.lib /nologo /dll /machine:I386 /libpath:"../expat" + +!ELSEIF "$(CFG)" == "libwbxml2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBWBXML2_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../expat" /I "../leaktrack" /D "_DEBUG" /D "WBXML_LIB_VERBOSE" /D "WBXML_USE_LEAKTRACKER" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBWBXML2_EXPORTS" /D "WBXML_SUPPORT_WML" /D "WBXML_SUPPORT_WTA" /D "WBXML_SUPPORT_SI" /D "WBXML_SUPPORT_SL" /D "WBXML_SUPPORT_CO" /D "WBXML_SUPPORT_PROV" /D "WBXML_SUPPORT_EMN" /D "WBXML_SUPPORT_DRMREL" /D "WBXML_SUPPORT_OTA_SETTINGS" /D "WBXML_SUPPORT_SYNCML" /D "WBXML_SUPPORT_WV" /D "WBXML_SUPPORT_AIRSYNC" /D "WBXML_ENCODER_USE_STRTBL" /D "HAVE_EXPAT" /D "WBXML_WRAPPERS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libexpat.lib leaktrack.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../expat" /libpath:"../leaktrack" + +!ENDIF + +# Begin Target + +# Name "libwbxml2 - Win32 Release" +# Name "libwbxml2 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\src\wbxml_base64.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_buffers.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_charset.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_conv.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_elt.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_encoder.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_errors.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_lists.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_log.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_mem.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_parser.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_tables.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_tree.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_tree_clb_wbxml.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_tree_clb_xml.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_wrap_syncml.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\src\wbxml.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_base64.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_buffers.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_charset.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_conv.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_elt.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_encoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_errors.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_handlers.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_lists.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_log.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_mem.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_parser.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_tables.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_tree.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_tree_clb_wbxml.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_tree_clb_xml.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\wbxml_wrap_syncml.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/win32/wbxml2xml/wbxml2xml.dsp b/win32/wbxml2xml/wbxml2xml.dsp new file mode 100644 index 0000000..4d5c24e --- /dev/null +++ b/win32/wbxml2xml/wbxml2xml.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="wbxml2xml" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=wbxml2xml - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "wbxml2xml.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "wbxml2xml.mak" CFG="wbxml2xml - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "wbxml2xml - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "wbxml2xml - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "wbxml2xml - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../src" /I "../expat" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "WBXML_SUPPORT_WML" /D "WBXML_SUPPORT_WTA" /D "WBXML_SUPPORT_SI" /D "WBXML_SUPPORT_SL" /D "WBXML_SUPPORT_CO" /D "WBXML_SUPPORT_PROV" /D "WBXML_SUPPORT_EMN" /D "WBXML_SUPPORT_DRMREL" /D "WBXML_SUPPORT_OTA_SETTINGS" /D "WBXML_SUPPORT_SYNCML" /D "WBXML_SUPPORT_WV" /D "WBXML_SUPPORT_AIRSYNC" /D "WBXML_ENCODER_USE_STRTBL" /D "HAVE_EXPAT" /D "WBXML_WRAPPERS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libwbxml2.lib /nologo /subsystem:console /machine:I386 /libpath:"../libwbxml2/Release" + +!ELSEIF "$(CFG)" == "wbxml2xml - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../src" /I "../expat" /I "../leaktrack" /D "_DEBUG" /D "WBXML_LIB_VERBOSE" /D "WBXML_USE_LEAKTRACKER" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "WBXML_SUPPORT_WML" /D "WBXML_SUPPORT_WTA" /D "WBXML_SUPPORT_SI" /D "WBXML_SUPPORT_SL" /D "WBXML_SUPPORT_CO" /D "WBXML_SUPPORT_PROV" /D "WBXML_SUPPORT_EMN" /D "WBXML_SUPPORT_DRMREL" /D "WBXML_SUPPORT_OTA_SETTINGS" /D "WBXML_SUPPORT_SYNCML" /D "WBXML_SUPPORT_WV" /D "WBXML_SUPPORT_AIRSYNC" /D "WBXML_ENCODER_USE_STRTBL" /D "HAVE_EXPAT" /D "WBXML_WRAPPERS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libwbxml2.lib leaktrack.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../libwbxml2/Debug" /libpath:"../leaktrack" + +!ENDIF + +# Begin Target + +# Name "wbxml2xml - Win32 Release" +# Name "wbxml2xml - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\tools\attgetopt.c +# End Source File +# Begin Source File + +SOURCE=..\..\tools\wbxml2xml_tool.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\tools\getopt.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/win32/xml2wbxml/xml2wbxml.dsp b/win32/xml2wbxml/xml2wbxml.dsp new file mode 100644 index 0000000..4dda758 --- /dev/null +++ b/win32/xml2wbxml/xml2wbxml.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="xml2wbxml" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=xml2wbxml - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "xml2wbxml.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "xml2wbxml.mak" CFG="xml2wbxml - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "xml2wbxml - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "xml2wbxml - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "xml2wbxml - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../src" /I "../expat" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "WBXML_SUPPORT_WML" /D "WBXML_SUPPORT_WTA" /D "WBXML_SUPPORT_SI" /D "WBXML_SUPPORT_SL" /D "WBXML_SUPPORT_CO" /D "WBXML_SUPPORT_PROV" /D "WBXML_SUPPORT_EMN" /D "WBXML_SUPPORT_DRMREL" /D "WBXML_SUPPORT_OTA_SETTINGS" /D "WBXML_SUPPORT_SYNCML" /D "WBXML_SUPPORT_WV" /D "WBXML_SUPPORT_AIRSYNC" /D "WBXML_ENCODER_USE_STRTBL" /D "HAVE_EXPAT" /D "WBXML_WRAPPERS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libwbxml2.lib /nologo /subsystem:console /machine:I386 /libpath:"../libwbxml2/Release" + +!ELSEIF "$(CFG)" == "xml2wbxml - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../src" /I "../expat" /I "../leaktrack" /D "_DEBUG" /D "WBXML_LIB_VERBOSE" /D "WBXML_USE_LEAKTRACKER" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "WBXML_SUPPORT_WML" /D "WBXML_SUPPORT_WTA" /D "WBXML_SUPPORT_SI" /D "WBXML_SUPPORT_SL" /D "WBXML_SUPPORT_CO" /D "WBXML_SUPPORT_PROV" /D "WBXML_SUPPORT_EMN" /D "WBXML_SUPPORT_DRMREL" /D "WBXML_SUPPORT_OTA_SETTINGS" /D "WBXML_SUPPORT_SYNCML" /D "WBXML_SUPPORT_WV" /D "WBXML_SUPPORT_AIRSYNC" /D "WBXML_ENCODER_USE_STRTBL" /D "HAVE_EXPAT" /D "WBXML_WRAPPERS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libwbxml2.lib leaktrack.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../libwbxml2/Debug" /libpath:"../leaktrack" + +!ENDIF + +# Begin Target + +# Name "xml2wbxml - Win32 Release" +# Name "xml2wbxml - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\tools\attgetopt.c +# End Source File +# Begin Source File + +SOURCE=..\..\tools\xml2wbxml_tool.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\tools\getopt.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project