From: jk7744.park Date: Sun, 1 Feb 2015 05:36:47 +0000 (+0900) Subject: tizen 2.3 release X-Git-Tag: submit/tizen_2.3/20150202.081957 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Ftags%2Fsubmit%2Ftizen_2.3%2F20150202.081957;p=framework%2Fweb%2Fwearable%2Fwrt-commons.git tizen 2.3 release --- diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..4c72b9c --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +*.log +*.a +*.o +*.so +*.so.* +*.sql +*.db +*.db-journal +*.pc + +CMakeCache.txt +CMakeFiles +install_manifest.txt +cmake_install.cmake +Makefile + +documentation.list +modules/widget_dao/database_checksum.h +modules/security_origin_dao/database_checksum_security_origin.h +modules/custom_handler_dao/database_checksum_custom_handler.h +modules/certificate_dao/database_checksum_certificage.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..bc14fc7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,202 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# + +# Check minimum CMake version +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# Project name +PROJECT(dpl) + +STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}") +ADD_DEFINITIONS("-DAPI_VERSION=\"$(API_VERSION)\"") + +# Comment this to disable control of global settings with environment variable +ADD_DEFINITIONS("-DGLOBAL_SETTINGS_CONTROL") + +# Build type +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE "Release") +ENDIF(NOT CMAKE_BUILD_TYPE) + +# Options +OPTION(DPL_LOG "DPL logs status" OFF) +IF(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling") + MESSAGE(STATUS "Logging enabled for DPL") + ADD_DEFINITIONS("-DDPL_LOGS_ENABLED") +ELSE(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling") + MESSAGE(STATUS "Logging disabled for DPL") +ENDIF(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling") + +OPTION(WITH_TESTS "Build tests" OFF) +OPTION(WITH_CHILD "Build additional test subdirectory. WITH_TEST must be ON" OFF) + +# Compiler flags +SET(CMAKE_C_FLAGS_PROFILING "-O2") +SET(CMAKE_CXX_FLAGS_PROFILING "-O2 -std=c++0x") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -std=c++0x -g") +SET(CMAKE_C_FLAGS_RELEASE "-Os") +SET(CMAKE_CXX_FLAGS_RELEASE "-Os -std=c++0x -fvisibility-inlines-hidden") +SET(CMAKE_CXX_FLAGS_CCOV "-O0 -std=c++0x -g --coverage") + +ADD_DEFINITIONS("-fPIC") # If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC. (BJ: our ARM too?) + +# CMake settings +MESSAGE(STATUS "========================================") +MESSAGE(STATUS "CMAKE_BINARY_DIR: " ${CMAKE_BINARY_DIR}) +MESSAGE(STATUS "CMAKE_CURRENT_BINARY_DIR: " ${CMAKE_CURRENT_BINARY_DIR}) +MESSAGE(STATUS "CMAKE_SOURCE_DIR: " ${CMAKE_SOURCE_DIR}) +MESSAGE(STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR}) +MESSAGE(STATUS "PROJECT_BINARY_DIR: " ${PROJECT_BINARY_DIR}) +MESSAGE(STATUS "PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR}) +MESSAGE(STATUS "EXECUTABLE_OUTPUT_PATH: " ${EXECUTABLE_OUTPUT_PATH}) +MESSAGE(STATUS "LIBRARY_OUTPUT_PATH: " ${LIBRARY_OUTPUT_PATH}) +MESSAGE(STATUS "CMAKE_MODULE_PATH: " ${CMAKE_MODULE_PATH}) +MESSAGE(STATUS "CMAKE_COMMAND: " ${CMAKE_COMMAND}) +MESSAGE(STATUS "CMAKE_ROOT: " ${CMAKE_ROOT}) +MESSAGE(STATUS "CMAKE_CURRENT_LIST_FILE: " ${CMAKE_CURRENT_LIST_FILE}) +MESSAGE(STATUS "CMAKE_CURRENT_LIST_LINE: " ${CMAKE_CURRENT_LIST_LINE}) +MESSAGE(STATUS "CMAKE_INCLUDE_PATH: " ${CMAKE_INCLUDE_PATH}) +MESSAGE(STATUS "CMAKE_LIBRARY_PATH: " ${CMAKE_LIBRARY_PATH}) +MESSAGE(STATUS "CMAKE_SYSTEM: " ${CMAKE_SYSTEM}) +MESSAGE(STATUS "CMAKE_SYSTEM_NAME: " ${CMAKE_SYSTEM_NAME}) +MESSAGE(STATUS "CMAKE_SYSTEM_VERSION: " ${CMAKE_SYSTEM_VERSION}) +MESSAGE(STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR}) +MESSAGE(STATUS "UNIX: " ${UNIX}) +MESSAGE(STATUS "WIN32: " ${WIN32}) +MESSAGE(STATUS "APPLE: " ${APPLE}) +MESSAGE(STATUS "MINGW: " ${MINGW}) +MESSAGE(STATUS "CYGWIN: " ${CYGWIN}) +MESSAGE(STATUS "BORLAND: " ${BORLAND}) +MESSAGE(STATUS "MSVC: " ${MSVC}) +MESSAGE(STATUS "MSVC_IDE: " ${MSVC_IDE}) +MESSAGE(STATUS "MSVC60: " ${MSVC60}) +MESSAGE(STATUS "MSVC70: " ${MSVC70}) +MESSAGE(STATUS "MSVC71: " ${MSVC71}) +MESSAGE(STATUS "MSVC80: " ${MSVC80}) +MESSAGE(STATUS "CMAKE_COMPILER_2005: " ${CMAKE_COMPILER_2005}) +MESSAGE(STATUS "CMAKE_SKIP_RULE_DEPENDENCY: " ${CMAKE_SKIP_RULE_DEPENDENCY}) +MESSAGE(STATUS "CMAKE_SKIP_INSTALL_ALL_DEPENDENCY: " ${CMAKE_SKIP_INSTALL_ALL_DEPENDENCY}) +MESSAGE(STATUS "CMAKE_SKIP_RPATH: " ${CMAKE_SKIP_RPATH}) +MESSAGE(STATUS "CMAKE_VERBOSE_MAKEFILE: " ${CMAKE_VERBOSE_MAKEFILE}) +MESSAGE(STATUS "CMAKE_SUPPRESS_REGENERATION: " ${CMAKE_SUPPRESS_REGENERATION}) +MESSAGE(STATUS "CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS}) +MESSAGE(STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS}) +MESSAGE(STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE}) +MESSAGE(STATUS "BUILD_SHARED_LIBS: " ${BUILD_SHARED_LIBS}) +MESSAGE(STATUS "CMAKE_C_COMPILER: " ${CMAKE_C_COMPILER}) +MESSAGE(STATUS "CMAKE_CXX_COMPILER: " ${CMAKE_CXX_COMPILER}) +MESSAGE(STATUS "CMAKE_COMPILER_IS_GNUCC: " ${CMAKE_COMPILER_IS_GNUCC}) +MESSAGE(STATUS "CMAKE_COMPILER_IS_GNUCXX : " ${CMAKE_COMPILER_IS_GNUCXX}) +MESSAGE(STATUS "CMAKE_AR: " ${CMAKE_AR}) +MESSAGE(STATUS "CMAKE_RANLIB: " ${CMAKE_RANLIB}) +MESSAGE(STATUS "WITH_TESTS: " ${WITH_TESTS}) +MESSAGE(STATUS "WITH_CHILD: " ${WITH_CHILD}) +MESSAGE(STATUS "========================================") + +# Compiler flags +ADD_DEFINITIONS("-fvisibility=default") # mark all exported symbols as visible + +# Warnings mode +#ADD_DEFINITIONS("-Werror") # Make all warnings into errors. + +# Warning flags +ADD_DEFINITIONS("-Wall") # Generate all warnings +ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings +ADD_DEFINITIONS("-pedantic") # Accept only pedantic code +#ADD_DEFINITIONS("-Weffc++") # Accept only effective C++ code +ADD_DEFINITIONS("-Wwrite-strings") # Do not accept writing to contant string memory +ADD_DEFINITIONS("-Winit-self") # Do not accept initializing variable with itself +ADD_DEFINITIONS("-Wcast-align") # Do not accept misaligning with casting +ADD_DEFINITIONS("-Wcast-qual") # Do not accept removing qualifiers with casting +#ADD_DEFINITIONS("-Wold-style-cast") # Do not accept old style casting +ADD_DEFINITIONS("-Wpointer-arith") # Warn about void pointer arthimetic +ADD_DEFINITIONS("-Wstrict-aliasing") # Ensure strict aliasing +ADD_DEFINITIONS("-Wuninitialized") # Do not accept uninitialized variables +ADD_DEFINITIONS("-Wmissing-declarations") # Warn about global and non-accesible functions +ADD_DEFINITIONS("-Woverloaded-virtual") # Warn about incidental overiding non-virtual base methods +ADD_DEFINITIONS("-Wnon-virtual-dtor") # Warn about non-virtual destructor +ADD_DEFINITIONS("-Wctor-dtor-privacy") # Warn about useless and non-constructible classes +#ADD_DEFINITIONS("-Wlong-long") # Do not allow using long long +#ADD_DEFINITIONS("-Wunreachable-code") # Warn about unreachable code +ADD_DEFINITIONS("-Wfloat-equal") # Do not accept comparing floating points with equal operator +ADD_DEFINITIONS("-Wabi") # Warn about possible ABI problems +ADD_DEFINITIONS("-Wswitch-enum") # Check switch enumeration +ADD_DEFINITIONS("-Wformat=2") # Check printf formatting +ADD_DEFINITIONS("-Wundef") # Warn if an undefined identifier is evaluated in an @if directive. +ADD_DEFINITIONS("-Wshadow") # Warn whenever a local variable shadows another local variable, parameter or global variable or whenever a built-in function is shadowed +ADD_DEFINITIONS("-Wconversion") # Warn for implicit conversions that may alter a value +ADD_DEFINITIONS("-Wlogical-op") # Warn about suspicious uses of logical operators in expressions +#ADD_DEFINITIONS("-Waggregate-return") # Warn if any functions that return structures or unions are defined or called. +ADD_DEFINITIONS("-Wmissing-field-initializers") # Warn if a structure's initializer has some fields missing. +ADD_DEFINITIONS("-Wredundant-decls") # Warn if anything is declared more than once in the same scope, even in cases where multiple declaration is valid and changes nothing. +#ADD_DEFINITIONS("-Wmissing-include-dirs") # Warn if a user-supplied include directory does not exist. +ADD_DEFINITIONS("-Wswitch-default") # Warn whenever a switch statement does not have a default case. +ADD_DEFINITIONS("-Wsync-nand") # Warn when __sync_fetch_and_nand and __sync_nand_and_fetch built-in functions are used. These functions changed semantics in GCC 4.4. +ADD_DEFINITIONS("-Wunused") # All the above -Wunused options combined. +ADD_DEFINITIONS("-Wstrict-overflow=5") # Also warn about cases where the compiler reduces the magnitude of a constant involved in a comparison. +#ADD_DEFINITIONS("-Wunsafe-loop-optimizations") # Warn if the loop cannot be optimized because the compiler could not assume anything on the bounds of the loop indices. With -funsafe-loop-optimizations warn if the compiler made such assumptions. +#ADD_DEFINITIONS("-Wmissing-format-attribute") # Warn about function pointers which might be candidates for format attributes. +#ADD_DEFINITIONS("-Wpadded") # Warn if padding is included in a structure, either to align an element of the structure or to align the whole structure. +#ADD_DEFINITIONS("-Winline") # Warn if a function can not be inlined and it was declared as inline. +ADD_DEFINITIONS("-Wdisabled-optimization") # Warn if a requested optimization pass is disabled. +ADD_DEFINITIONS("-std=c++0x") + +# +# Core library files +# +# Define all core library headers and sources. As detail files +# are usually templated and though recompiled in each file, we +# have to compile full source for each target. +# + +# Set names of binaries being created +SET(TARGET_DPL_EFL "lib${PROJECT_NAME}-efl") +SET(TARGET_DPL_DBUS_EFL "lib${PROJECT_NAME}-dbus-efl") +SET(TARGET_DPL_DB_EFL "lib${PROJECT_NAME}-db-efl") +SET(TARGET_DPL_EVENT_EFL "lib${PROJECT_NAME}-event-efl") +SET(TARGET_DPL_SOCKET_EFL "lib${PROJECT_NAME}-socket-efl") +SET(TARGET_DPL_RPC_EFL "lib${PROJECT_NAME}-rpc-efl") +SET(TARGET_DPL_TEST_ENGINE_EFL "lib${PROJECT_NAME}-test-efl") +SET(TARGET_DPL_LOG_EFL "lib${PROJECT_NAME}-log-efl") +SET(TARGET_WRT_DAO_RW_LIB "dpl-wrt-dao-rw") +SET(TARGET_WRT_DAO_RO_LIB "dpl-wrt-dao-ro") +SET(TARGET_CUSTOM_HANDLER_DAO_RW_LIB "wrt-commons-custom-handler-dao-rw") +SET(TARGET_CUSTOM_HANDLER_DAO_RO_LIB "wrt-commons-custom-handler-dao-ro") +SET(TARGET_SECURITY_ORIGIN_DAO_LIB "wrt-commons-security-origin-dao") +SET(TARGET_CERTIFICATE_DAO_LIB "wrt-commons-certificate-dao") +SET(TARGET_DPL_UTILS_EFL "lib${PROJECT_NAME}-utils-efl") +SET(TARGET_I18N_DAO_RO_LIB "wrt-commons-i18n-dao-ro") +SET(TARGET_WIDGET_INTERFACE_DAO_LIB "wrt-commons-widget-interface-dao") + +macro(configure_and_install_pkg PKG_FILE) + CONFIGURE_FILE(${PKG_FILE}.in ${PKG_FILE} @ONLY) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PKG_FILE} DESTINATION lib/pkgconfig) +endmacro(configure_and_install_pkg) + +ADD_SUBDIRECTORY(modules) + +ADD_SUBDIRECTORY(build) +ADD_SUBDIRECTORY(etc) + +IF(WITH_TESTS) + ADD_SUBDIRECTORY(tests) +ENDIF(WITH_TESTS) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..247c97d --- /dev/null +++ b/LICENSE @@ -0,0 +1,203 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..ded3804 --- /dev/null +++ b/NOTICE @@ -0,0 +1 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. \ No newline at end of file diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt new file mode 100644 index 0000000..b94d51f --- /dev/null +++ b/build/CMakeLists.txt @@ -0,0 +1,36 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +ADD_SUBDIRECTORY(core) +ADD_SUBDIRECTORY(dbus) +ADD_SUBDIRECTORY(db) +ADD_SUBDIRECTORY(event) +ADD_SUBDIRECTORY(socket) +ADD_SUBDIRECTORY(rpc) +ADD_SUBDIRECTORY(test) +#ADD_SUBDIRECTORY(log) +ADD_SUBDIRECTORY(widget_dao) +ADD_SUBDIRECTORY(security_origin_dao) +ADD_SUBDIRECTORY(custom_handler_dao) +ADD_SUBDIRECTORY(utils) +ADD_SUBDIRECTORY(support) +ADD_SUBDIRECTORY(certificate_dao) +ADD_SUBDIRECTORY(i18n) +ADD_SUBDIRECTORY(widget_interface_dao) diff --git a/build/certificate_dao/CMakeLists.txt b/build/certificate_dao/CMakeLists.txt new file mode 100755 index 0000000..037a7c2 --- /dev/null +++ b/build/certificate_dao/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Leerang Song (leerang.song@samsung.com) +# @brief +# + +configure_and_install_pkg(wrt-commons-certificate-dao.pc) + diff --git a/build/certificate_dao/wrt-commons-certificate-dao.pc.in b/build/certificate_dao/wrt-commons-certificate-dao.pc.in new file mode 100644 index 0000000..903dc95 --- /dev/null +++ b/build/certificate_dao/wrt-commons-certificate-dao.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +exec_prefix=${prefix} + +libdir=${prefix}/lib +includedir=${prefix}/include +Name: wrt-commons-certificate-dao +Description: wrt-commons-certificate-dao + +Version: @VERSION@ +Requires: dpl-efl +Libs: -lwrt-commons-certificate-dao -L${libdir} +Cflags: -I${includedir}/dpl-efl diff --git a/build/core/CMakeLists.txt b/build/core/CMakeLists.txt new file mode 100644 index 0000000..d67e246 --- /dev/null +++ b/build/core/CMakeLists.txt @@ -0,0 +1,79 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL + ecore + appcore-efl + openssl + dlog + vconf + libpcrecpp + icu-uc + minizip + REQUIRED) + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} + ${DPL_CORE_INCLUDE_DIR} +) + +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_INCLUDE_DIRS}) + +LINK_DIRECTORIES(${SYS_EFL_LIBRARY_DIRS}) + +# Base EFL based DPL library +SET(DPL_EFL_LIBRARY "${PROJECT_NAME}-efl") + +# Build shared library +ADD_LIBRARY(${TARGET_DPL_EFL} SHARED + ${DPL_CORE_SOURCES} + ${DPL_LOG_SOURCES} +) + +TARGET_LINK_LIBRARIES(${TARGET_DPL_EFL} ${SYS_EFL_LIBRARIES} "-lrt") + +# Target library properties +SET_TARGET_PROPERTIES(${TARGET_DPL_EFL} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION} + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME ${DPL_EFL_LIBRARY}) + +# Install libraries +INSTALL(TARGETS ${TARGET_DPL_EFL} + DESTINATION lib) + +# Install detail headers +INSTALL(FILES ${DPL_CORE_EFL_DETAIL_HEADERS} + DESTINATION include/dpl-efl/dpl) + +# Install core headers +INSTALL(FILES ${DPL_CORE_HEADERS} + DESTINATION include/dpl-efl/dpl) + +# Install log headers +INSTALL(FILES ${DPL_LOG_HEADERS} + DESTINATION include/dpl-efl/dpl/log) + +# Install pkgconfig script +configure_and_install_pkg(dpl-efl.pc) diff --git a/build/core/DESCRIPTION b/build/core/DESCRIPTION new file mode 100644 index 0000000..f7f1581 --- /dev/null +++ b/build/core/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +EFL support diff --git a/build/core/dpl-efl.pc.in b/build/core/dpl-efl.pc.in new file mode 100644 index 0000000..6d2a882 --- /dev/null +++ b/build/core/dpl-efl.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-efl +Description: DPL - EFL based +Version: @VERSION@ +Requires: ecore appcore-efl openssl dlog vconf +Libs: -L${libdir} -ldpl-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/custom_handler_dao/CMakeLists.txt b/build/custom_handler_dao/CMakeLists.txt new file mode 100644 index 0000000..26e701c --- /dev/null +++ b/build/custom_handler_dao/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) +# @brief +# + +configure_and_install_pkg(wrt-commons-custom-handler-dao-ro.pc) +configure_and_install_pkg(wrt-commons-custom-handler-dao-rw.pc) diff --git a/build/custom_handler_dao/wrt-commons-custom-handler-dao-ro.pc.in b/build/custom_handler_dao/wrt-commons-custom-handler-dao-ro.pc.in new file mode 100644 index 0000000..7cda187 --- /dev/null +++ b/build/custom_handler_dao/wrt-commons-custom-handler-dao-ro.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +exec_prefix=${prefix} + +libdir=${prefix}/lib +includedir=${prefix}/include +Name: wrt-commons-custom-handler-dao-ro +Description: wrt-commons-custom-handler-dao-ro + +Version: @VERSION@ +Requires: dpl-efl +Libs: -lwrt-commons-custom-handler-dao-ro -L${libdir} +Cflags: -I${includedir}/dpl-efl diff --git a/build/custom_handler_dao/wrt-commons-custom-handler-dao-rw.pc.in b/build/custom_handler_dao/wrt-commons-custom-handler-dao-rw.pc.in new file mode 100644 index 0000000..4cd2737 --- /dev/null +++ b/build/custom_handler_dao/wrt-commons-custom-handler-dao-rw.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +exec_prefix=${prefix} + +libdir=${prefix}/lib +includedir=${prefix}/include +Name: wrt-commons-custom-handler-dao-rw +Description: wrt-commons-custom-handler-dao-rw + +Version: @VERSION@ +Requires: dpl-efl wrt-commons-custom-handler-dao-ro +Libs: -lwrt-commons-custom-handler-dao-rw -lwrt-commons-custom-handler-dao-ro -L${libdir} +Cflags: -I${includedir}/dpl-efl diff --git a/build/db/CMakeLists.txt b/build/db/CMakeLists.txt new file mode 100644 index 0000000..29dd495 --- /dev/null +++ b/build/db/CMakeLists.txt @@ -0,0 +1,70 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_DB + sqlite3 + db-util + REQUIRED) + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} + ${DPL_CORE_INCLUDE_DIR} + ${DPL_DB_INCLUDE_DIR} +) + +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_DB_INCLUDE_DIRS}) + +LINK_DIRECTORIES( + ${SYS_EFL_DB_LIBRARY_DIRS} +) + +# Base EFL based DPL library +SET(DPL_EFL_DB_LIBRARY "${PROJECT_NAME}-db-efl") + +# Build shared library + +ADD_LIBRARY(${TARGET_DPL_DB_EFL} SHARED ${DPL_DB_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_DPL_DB_EFL} + ${SYS_EFL_DB_LIBRARIES} + ${TARGET_DPL_EFL} +) + +# Target library properties +SET_TARGET_PROPERTIES(${TARGET_DPL_DB_EFL} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION} + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME ${DPL_EFL_DB_LIBRARY}) + +# Install libraries +INSTALL(TARGETS ${TARGET_DPL_DB_EFL} + DESTINATION lib) + +# Install detail headers +INSTALL(FILES ${DPL_DB_HEADERS} + DESTINATION include/dpl-efl/dpl/db) + +# Install pkgconfig script +configure_and_install_pkg(dpl-db-efl.pc) diff --git a/build/db/dpl-db-efl.pc.in b/build/db/dpl-db-efl.pc.in new file mode 100644 index 0000000..866bb0f --- /dev/null +++ b/build/db/dpl-db-efl.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-db-efl +Description: DPL DB - EFL based +Version: @VERSION@ +Requires: dpl-efl sqlite3 db-util +Libs: -L${libdir} -ldpl-db-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/dbus/CMakeLists.txt b/build/dbus/CMakeLists.txt new file mode 100644 index 0000000..59b2db1 --- /dev/null +++ b/build/dbus/CMakeLists.txt @@ -0,0 +1,72 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_DBUS + dbus-1 + gio-2.0 + REQUIRED) + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} + ${DPL_CORE_INCLUDE_DIR} + ${DPL_DBUS_INCLUDE_DIR} + ${DPL_EVENT_INCLUDE_DIR} +) + +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_DBUS_INCLUDE_DIRS}) + +LINK_DIRECTORIES( + ${SYS_EFL_DBUS_LIBRARY_DIRS} +) + +# Base EFL based DPL library +SET(DPL_EFL_DBUS_LIBRARY "${PROJECT_NAME}-dbus-efl") + +# Build shared library + +ADD_LIBRARY(${TARGET_DPL_DBUS_EFL} SHARED ${DPL_DBUS_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_DPL_DBUS_EFL} + ${SYS_EFL_DBUS_LIBRARIES} + ${TARGET_DPL_EFL} + ${TARGET_DPL_EVENT_EFL} +) + +# Target library properties +SET_TARGET_PROPERTIES(${TARGET_DPL_DBUS_EFL} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION} + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME ${DPL_EFL_DBUS_LIBRARY}) + +# Install libraries +INSTALL(TARGETS ${TARGET_DPL_DBUS_EFL} + DESTINATION lib) + +# Install detail headers +INSTALL(FILES ${DPL_DBUS_HEADERS} + DESTINATION include/dpl-efl/dpl/dbus) + +# Install pkgconfig script +configure_and_install_pkg(dpl-dbus-efl.pc) diff --git a/build/dbus/dpl-dbus-efl.pc.in b/build/dbus/dpl-dbus-efl.pc.in new file mode 100644 index 0000000..73f2c03 --- /dev/null +++ b/build/dbus/dpl-dbus-efl.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-dbus-efl +Description: DPL DBus - EFL based +Version: @VERSION@ +Requires: dbus-1 dpl-efl dpl-event-efl +Libs: -L${libdir} -ldpl-dbus-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/event/CMakeLists.txt b/build/event/CMakeLists.txt new file mode 100644 index 0000000..b023e0a --- /dev/null +++ b/build/event/CMakeLists.txt @@ -0,0 +1,72 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_EVENT + ecore + appcore-efl + vconf + REQUIRED +) + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} + ${DPL_CORE_INCLUDE_DIR} + ${DPL_EVENT_INCLUDE_DIR} + ${DPL_EVENT_INCLUDE_DIR} +) + +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_EVENT_INCLUDE_DIRS}) + +LINK_DIRECTORIES( + ${SYS_EFL_EVENT_LIBRARY_DIRS} +) + +# Base EFL based DPL library +SET(DPL_EFL_EVENT_LIBRARY "${PROJECT_NAME}-event-efl") + +# Build shared library + +ADD_LIBRARY(${TARGET_DPL_EVENT_EFL} SHARED ${DPL_EVENT_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_DPL_EVENT_EFL} + ${SYS_EFL_EVENT_LIBRARIES} + ${TARGET_DPL_EFL} +) + +# Target library properties +SET_TARGET_PROPERTIES(${TARGET_DPL_EVENT_EFL} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION} + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME ${DPL_EFL_EVENT_LIBRARY}) + +# Install libraries +INSTALL(TARGETS ${TARGET_DPL_EVENT_EFL} + DESTINATION lib) + +# Install detail headers +INSTALL(FILES ${DPL_EVENT_HEADERS} + DESTINATION include/dpl-efl/dpl/event) + +# Install pkgconfig script +configure_and_install_pkg(dpl-event-efl.pc) diff --git a/build/event/dpl-event-efl.pc.in b/build/event/dpl-event-efl.pc.in new file mode 100644 index 0000000..d4befbe --- /dev/null +++ b/build/event/dpl-event-efl.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-event-efl +Description: DPL Event - EFL based +Version: @VERSION@ +Requires: dpl-efl ecore appcore-efl vconf +Libs: -L${libdir} -ldpl-event-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/i18n/CMakeLists.txt b/build/i18n/CMakeLists.txt new file mode 100644 index 0000000..3d97f54 --- /dev/null +++ b/build/i18n/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) +# @brief +# + +configure_and_install_pkg(wrt-commons-i18n-dao-ro.pc) diff --git a/build/i18n/wrt-commons-i18n-dao-ro.pc.in b/build/i18n/wrt-commons-i18n-dao-ro.pc.in new file mode 100644 index 0000000..270630b --- /dev/null +++ b/build/i18n/wrt-commons-i18n-dao-ro.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +exec_prefix=${prefix} + +libdir=${prefix}/lib +includedir=${prefix}/include +Name: wrt-commons-i18n-dao-ro +Description: wrt-commons-i18n-dao-ro + +Version: @VERSION@ +Requires: dpl-efl +Libs: -lwrt-commons-i18n-dao-ro -L${libdir} +Cflags: -I${includedir}/dpl-efl diff --git a/build/log/CMakeLists.txt b/build/log/CMakeLists.txt new file mode 100644 index 0000000..47379d5 --- /dev/null +++ b/build/log/CMakeLists.txt @@ -0,0 +1,65 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_LOG + dlog + REQUIRED +) + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} +) + +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_LOG_INCLUDE_DIRS}) + +LINK_DIRECTORIES( + ${SYS_EFL_LOG_LIBRARY_DIRS} +) + +# Base EFL based DPL library +SET(DPL_EFL_LOG_LIBRARY "${PROJECT_NAME}-log-efl") + +# Build shared library + +ADD_LIBRARY(${TARGET_DPL_LOG_EFL} SHARED ${DPL_LOG_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_DPL_LOG_EFL} + ${SYS_EFL_LOG_LIBRARIES} +) + +# Target library properties +SET_TARGET_PROPERTIES(${TARGET_DPL_LOG_EFL} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION} + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME ${DPL_EFL_LOG_LIBRARY}) + +# Install libraries +INSTALL(TARGETS ${TARGET_DPL_LOG_EFL} + DESTINATION lib) + +INSTALL(FILES ${DPL_LOG_HEADERS} + DESTINATION include/dpl-efl/dpl/log) + +# Install pkgconfig script +configure_and_install_pkg(dpl-log-efl.pc) diff --git a/build/log/dpl-log-efl.pc.in b/build/log/dpl-log-efl.pc.in new file mode 100644 index 0000000..7f18689 --- /dev/null +++ b/build/log/dpl-log-efl.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-log-efl +Description: DPL Log Engine - EFL based +Version: @VERSION@ +Requires: dpl-efl dlog +Libs: -L${libdir} -ldpl-log-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/rpc/CMakeLists.txt b/build/rpc/CMakeLists.txt new file mode 100644 index 0000000..9c52217 --- /dev/null +++ b/build/rpc/CMakeLists.txt @@ -0,0 +1,75 @@ + +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_RPC + ecore + appcore-efl + REQUIRED +) + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} + ${DPL_CORE_INCLUDE_DIR} + ${DPL_SOCKET_INCLUDE_DIR} + ${DPL_EVENT_INCLUDE_DIR} + ${DPL_RPC_INCLUDE_DIR} +) + +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_RPC_INCLUDE_DIRS}) + +LINK_DIRECTORIES( + ${SYS_EFL_RPC_LIBRARY_DIRS} +) + +# Base EFL based DPL library +SET(DPL_EFL_RPC_LIBRARY "${PROJECT_NAME}-rpc-efl") + +# Build shared library + +ADD_LIBRARY(${TARGET_DPL_RPC_EFL} SHARED ${DPL_RPC_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_DPL_RPC_EFL} + ${SYS_EFL_RPC_LIBRARIES} + ${TARGET_DPL_EFL} + ${TARGET_DPL_EVENT_EFL} + ${TARGET_DPL_SOCKET_EFL} +) + +# Target library properties +SET_TARGET_PROPERTIES(${TARGET_DPL_RPC_EFL} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION} + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME ${DPL_EFL_RPC_LIBRARY}) + +# Install libraries +INSTALL(TARGETS ${TARGET_DPL_RPC_EFL} + DESTINATION lib) + +# Install detail headers +INSTALL(FILES ${DPL_RPC_HEADERS} + DESTINATION include/dpl-efl/dpl/rpc) + +# Install pkgconfig script +configure_and_install_pkg(dpl-rpc-efl.pc) diff --git a/build/rpc/dpl-rpc-efl.pc.in b/build/rpc/dpl-rpc-efl.pc.in new file mode 100644 index 0000000..d857bbe --- /dev/null +++ b/build/rpc/dpl-rpc-efl.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-rpc-efl +Description: DPL RPC - EFL based +Version: @VERSION@ +Requires: dpl-efl dpl-event-efl dpl-socket-efl +Libs: -L${libdir} -ldpl-rpc-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/security_origin_dao/CMakeLists.txt b/build/security_origin_dao/CMakeLists.txt new file mode 100644 index 0000000..ee0dcf8 --- /dev/null +++ b/build/security_origin_dao/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Jihoon Chung (jihoon.chung@samsung.com) +# @brief +# + +configure_and_install_pkg(wrt-commons-security-origin-dao.pc) + diff --git a/build/security_origin_dao/wrt-commons-security-origin-dao.pc.in b/build/security_origin_dao/wrt-commons-security-origin-dao.pc.in new file mode 100644 index 0000000..2ab81cb --- /dev/null +++ b/build/security_origin_dao/wrt-commons-security-origin-dao.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +exec_prefix=${prefix} + +libdir=${prefix}/lib +includedir=${prefix}/include +Name: wrt-commons-security-origin-dao +Description: wrt-commons-security-origin-dao + +Version: @VERSION@ +Requires: dpl-efl +Libs: -lwrt-commons-security-origin-dao -L${libdir} +Cflags: -I${includedir}/dpl-efl diff --git a/build/socket/CMakeLists.txt b/build/socket/CMakeLists.txt new file mode 100644 index 0000000..3ef033f --- /dev/null +++ b/build/socket/CMakeLists.txt @@ -0,0 +1,72 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_SOCKET + ecore + appcore-efl + REQUIRED +) + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} + ${DPL_CORE_INCLUDE_DIR} + ${DPL_SOCKET_INCLUDE_DIR} + ${DPL_EVENT_INCLUDE_DIR} +) + +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_SOCKET_INCLUDE_DIRS}) + +LINK_DIRECTORIES( + ${SYS_EFL_SOCKET_LIBRARY_DIRS} +) + +# Base EFL based DPL library +SET(DPL_EFL_SOCKET_LIBRARY "${PROJECT_NAME}-socket-efl") + +# Build shared library + +ADD_LIBRARY(${TARGET_DPL_SOCKET_EFL} SHARED ${DPL_SOCKET_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_DPL_SOCKET_EFL} + ${SYS_EFL_SOCKET_LIBRARIES} + ${TARGET_DPL_EFL} + ${TARGET_DPL_EVENT_EFL} +) + +# Target library properties +SET_TARGET_PROPERTIES(${TARGET_DPL_SOCKET_EFL} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION} + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME ${DPL_EFL_SOCKET_LIBRARY}) + +# Install libraries +INSTALL(TARGETS ${TARGET_DPL_SOCKET_EFL} + DESTINATION lib) + +# Install detail headers +INSTALL(FILES ${DPL_SOCKET_HEADERS} + DESTINATION include/dpl-efl/dpl/socket) + +# Install pkgconfig script +configure_and_install_pkg(dpl-socket-efl.pc) diff --git a/build/socket/dpl-socket-efl.pc.in b/build/socket/dpl-socket-efl.pc.in new file mode 100644 index 0000000..1e1409a --- /dev/null +++ b/build/socket/dpl-socket-efl.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-socket-efl +Description: DPL Socket - EFL based +Version: @VERSION@ +Requires: dpl-efl dpl-event-efl +Libs: -L${libdir} -ldpl-socket-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/support/CMakeLists.txt b/build/support/CMakeLists.txt new file mode 100644 index 0000000..f0a67a4 --- /dev/null +++ b/build/support/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# Install headers +INSTALL(FILES ${DPL_WRT_ENGINE_HEADERS} + DESTINATION include/dpl-efl/wrt-commons) + +# Install pkgconfig script +configure_and_install_pkg(wrt-plugins-types.pc) diff --git a/build/support/wrt-plugins-types.pc.in b/build/support/wrt-plugins-types.pc.in new file mode 100644 index 0000000..b35b9b4 --- /dev/null +++ b/build/support/wrt-plugins-types.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: wrt-plugins-types +Description: Header for plugins types +Version: @VERSION@ +Requires: +Libs: +Cflags: -I${includedir}/dpl-efl/wrt-commons diff --git a/build/test/CMakeLists.txt b/build/test/CMakeLists.txt new file mode 100644 index 0000000..d992952 --- /dev/null +++ b/build/test/CMakeLists.txt @@ -0,0 +1,70 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_TEST_ENGINE + appcore-efl + libxml-2.0 + REQUIRED) + + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} + ${DPL_CORE_INCLUDE_DIR} + ${DPL_TEST_ENGINE_INCLUDE_DIR} + ${DPL_UTILS_INCLUDE_DIR} +) + +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_TEST_ENGINE_INCLUDE_DIRS}) + +LINK_DIRECTORIES( + ${SYS_EFL_TEST_ENGINE_LIBRARY_DIRS} +) + +# Base EFL based DPL library +SET(DPL_EFL_TEST_ENGINE_LIBRARY "${PROJECT_NAME}-test-efl") + +# Build shared library + +ADD_LIBRARY(${TARGET_DPL_TEST_ENGINE_EFL} SHARED ${DPL_TEST_ENGINE_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_DPL_TEST_ENGINE_EFL} + ${TARGET_DPL_EFL} + ${TARGET_DPL_UTILS_EFL} +) + +# Target library properties +SET_TARGET_PROPERTIES(${TARGET_DPL_TEST_ENGINE_EFL} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION} + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME ${DPL_EFL_TEST_ENGINE_LIBRARY}) + +# Install libraries +INSTALL(TARGETS ${TARGET_DPL_TEST_ENGINE_EFL} + DESTINATION lib) + +# Install detail headers +INSTALL(FILES ${DPL_TEST_ENGINE_HEADERS} + DESTINATION include/dpl-efl/dpl/test) + +# Install pkgconfig script +configure_and_install_pkg(dpl-test-efl.pc) diff --git a/build/test/dpl-test-efl.pc.in b/build/test/dpl-test-efl.pc.in new file mode 100644 index 0000000..056ae09 --- /dev/null +++ b/build/test/dpl-test-efl.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-test-efl +Description: DPL Test Engine - EFL based +Version: @VERSION@ +Requires: dpl-efl libxml-2.0 +Libs: -L${libdir} -ldpl-test-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/utils/CMakeLists.txt b/build/utils/CMakeLists.txt new file mode 100644 index 0000000..ccc52ae --- /dev/null +++ b/build/utils/CMakeLists.txt @@ -0,0 +1,84 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Soyoung Kim (sy037.kim@samsung.com) +# @version 1.0 +# @brief +# + +# Check required modules +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SYS_EFL_UTILS + dlog + libiri + appcore-efl + libidn + REQUIRED +) + +# Add core include directories +INCLUDE_DIRECTORIES( + ${DPL_LOG_INCLUDE_DIR} + ${DPL_CORE_INCLUDE_DIR} + ${DPL_DB_INCLUDE_DIR} + ${DPL_UTILS_INCLUDE_DIR} + ${DPL_LOCALIZATION_INCLUDE_DIR} +) +INCLUDE_DIRECTORIES(SYSTEM ${SYS_EFL_UTILS_INCLUDE_DIRS}) + +INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/widget_dao/include) +INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/modules/vcore/src/vcore) + +LINK_DIRECTORIES( + ${SYS_EFL_UTILS_LIBRARY_DIRS} +) + +# Base EFL based DPL library +SET(DPL_EFL_UTILS_LIBRARY "${PROJECT_NAME}-utils-efl") + +# Build shared library + +ADD_LIBRARY(${TARGET_DPL_UTILS_EFL} SHARED + ${DPL_UTILS_SOURCES} + ${DPL_LOCALIZATION_SOURCES} +) + +TARGET_LINK_LIBRARIES(${TARGET_DPL_UTILS_EFL} + ${SYS_EFL_UTILS_LIBRARIES} + ${TARGET_DPL_EFL} + ${TARGET_WRT_DAO_RW_LIB} + ${SYS_EFL_DB_LIBRARIES} +) + +# Target library properties +SET_TARGET_PROPERTIES(${TARGET_DPL_UTILS_EFL} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION} + CLEAN_DIRECT_OUTPUT 1 + OUTPUT_NAME ${DPL_EFL_UTILS_LIBRARY}) + +# Install libraries +INSTALL(TARGETS ${TARGET_DPL_UTILS_EFL} + DESTINATION lib) + +# Install detail headers +INSTALL(FILES ${DPL_UTILS_HEADERS} + DESTINATION include/dpl-efl/dpl/utils) + +INSTALL(FILES ${DPL_LOCALIZATION_HEADERS} + DESTINATION include/dpl-efl/dpl/localization) + +# Install pkgconfig script +configure_and_install_pkg(dpl-utils-efl.pc) diff --git a/build/utils/dpl-utils-efl.pc.in b/build/utils/dpl-utils-efl.pc.in new file mode 100644 index 0000000..8e1d4c9 --- /dev/null +++ b/build/utils/dpl-utils-efl.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: dpl-utils-efl +Description: DPL UTILS - EFL based +Version: @VERSION@ +Requires: dpl-efl +Libs: -L${libdir} -ldpl-utils-efl +Cflags: -I${includedir}/dpl-efl diff --git a/build/widget_dao/CMakeLists.txt b/build/widget_dao/CMakeLists.txt new file mode 100644 index 0000000..0590e56 --- /dev/null +++ b/build/widget_dao/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) +# @brief +# + +configure_and_install_pkg(dpl-wrt-dao-ro.pc) +configure_and_install_pkg(dpl-wrt-dao-rw.pc) diff --git a/build/widget_dao/dpl-wrt-dao-ro.pc.in b/build/widget_dao/dpl-wrt-dao-ro.pc.in new file mode 100644 index 0000000..d2d112b --- /dev/null +++ b/build/widget_dao/dpl-wrt-dao-ro.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +exec_prefix=${prefix} + +libdir=${prefix}/lib +includedir=${prefix}/include +Name: dpl-wrt-dao-ro +Description: dpl-wrt-dao-ro + +Version: @VERSION@ +Requires: dpl-efl libxml-2.0 +Libs: -ldpl-wrt-dao-ro -L${libdir} +Cflags: -I${includedir}/dpl-efl diff --git a/build/widget_dao/dpl-wrt-dao-rw.pc.in b/build/widget_dao/dpl-wrt-dao-rw.pc.in new file mode 100644 index 0000000..c71e58d --- /dev/null +++ b/build/widget_dao/dpl-wrt-dao-rw.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +exec_prefix=${prefix} + +libdir=${prefix}/lib +includedir=${prefix}/include +Name: dpl-wrt-dao-rw +Description: dpl-wrt-dao-rw + +Version: @VERSION@ +Requires: dpl-efl dpl-wrt-dao-ro libxml-2.0 +Libs: -ldpl-wrt-dao-rw -ldpl-wrt-dao-ro -L${libdir} +Cflags: -I${includedir}/dpl-efl diff --git a/build/widget_interface_dao/CMakeLists.txt b/build/widget_interface_dao/CMakeLists.txt new file mode 100644 index 0000000..e726271 --- /dev/null +++ b/build/widget_interface_dao/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Jihoon Chung (jihoon.chung@samsung.com) +# @brief +# + +configure_and_install_pkg(wrt-commons-widget-interface-dao.pc) + diff --git a/build/widget_interface_dao/wrt-commons-widget-interface-dao.pc.in b/build/widget_interface_dao/wrt-commons-widget-interface-dao.pc.in new file mode 100644 index 0000000..348b178 --- /dev/null +++ b/build/widget_interface_dao/wrt-commons-widget-interface-dao.pc.in @@ -0,0 +1,12 @@ +prefix=/usr +exec_prefix=${prefix} + +libdir=${prefix}/lib +includedir=${prefix}/include +Name: wrt-commons-widget-interface-dao +Description: wrt-commons-widget-interface-dao + +Version: @VERSION@ +Requires: dpl-efl +Libs: -lwrt-commons-widget-interface-dao -L${libdir} +Cflags: -I${includedir}/dpl-efl diff --git a/dir-struct.py b/dir-struct.py new file mode 100755 index 0000000..13eb011 --- /dev/null +++ b/dir-struct.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python +# Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os +import re + + +def countLines(path): + with open(path) as f: + return len(f.readlines()) + +# RETURNS: ( +# short description (string or None) +# long decsription (array of strings or None) +# options: stop +def parseDescr(lines): + if len(lines) == 0: + return (None, None, False) + linesRest = None + if re.match( r"!!!options!!!", lines[0] ): + optStop = True + linesRest = lines[1:] + else: + optStop = False + linesRest = lines + if len(linesRest) == 0: + return(None,None,optStop) + short = linesRest[0].rstrip() + long = [] + for l in linesRest[1:]: + ll = l.rstrip() + if re.search( r"\S", ll ): + long.append( ll ) + if len(long) == 0: + long = None + + return (short, long, optStop) + +# RETURNS a tree with nodes like: ( +# path (string) +# short description (string or None) +# long decsription (array of strings or None) +# LOC (integer) +# list of subdirs (child nodes like this one) +def parseDir(path): + short = None + long = None + optStop = False + try: + with open( path+'/DESCRIPTION' ) as f: + short, long, optStop = parseDescr( f.readlines() ) + except IOError: + pass + dirs = [] + cntLines = 0 + for fname in os.listdir(path): + if fname != '.git' and os.path.isdir(path+'/'+fname): + subdir = parseDir(path+'/'+fname) + if optStop == False: + dirs.append(subdir) + (dummy0, dummy1, dummy2, subLines, dummy4) = subdir + cntLines += subLines + + if os.path.isfile(path+'/'+fname) \ + and not os.path.islink(path+'/'+fname): + cntLines += countLines(path+'/'+fname) + + return path, short, long, cntLines, dirs + + +### ##### PRINT AS TEXT +### +### def printTextSub(path,indent,withLongDesc): +### short, long, dirs, loc = parseDir(path) +### if short == None: +### p = re.sub(r"^\./", '', path) +### print '%s%s -- ' % (indent, p) +### else: +### p = re.sub(r"^\./", '', path) +### print '%s%s -- %s' % (indent, p, short) +### if withLongDesc: +### if long != None: +### print '' +### for line in long: +### print '%s%s' % (indent+' ',line) +### print '' +### for dir in dirs: +### printTextSub(path+'/'+dir, indent+' ', withLongDesc) +### +### def printText(path,withLongDesc): +### printTextSub(path,'',withLongDesc) +### +### def printTextWoMain(path,withLongDesc): +### short, long, dirs, loc = parseDir(path) +### for dir in dirs: +### printTextSub(path+'/'+dir, '', withLongDesc) +### + +##### PRINT AS a sort of CSV delimited by '|' + +# indent is a number (0..) +def printTabSub(tree,indent): + path, short, long, loc, subdirs = tree + p = re.sub(r"^\./", '', path) + m = re.search(r"/([^/]*$)", p) + if m != None: p = m.groups()[0] + if short == None: + print '%s%s|%d|' % (" "*indent, p, loc) + else: + print '%s%s|%d|%s' % (" "*indent, p, loc, short) + for dir in subdirs: + printTabSub(dir, indent+1) + +def printTab(tree): + printTabSub(tree,0) + +def printTabWoMain(tree): + path, short, long, loc, dirs = tree + for dir in dirs: + printTabSub(dir, 0) + + +##### MAIN + +tree = parseDir('.') +printTabWoMain(tree) + diff --git a/doc/DESCRIPTION b/doc/DESCRIPTION new file mode 100644 index 0000000..c3f01bd --- /dev/null +++ b/doc/DESCRIPTION @@ -0,0 +1 @@ +Documentation diff --git a/doc/doxyfile b/doc/doxyfile new file mode 100644 index 0000000..f058b7a --- /dev/null +++ b/doc/doxyfile @@ -0,0 +1,1600 @@ +# Doxyfile 1.6.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = DPL + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = YES + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set +# FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../core ../detail + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +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 \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = YES + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = NO + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = gif + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/doc/dpl_programming_guide.docx b/doc/dpl_programming_guide.docx new file mode 100644 index 0000000..f8e11e9 Binary files /dev/null and b/doc/dpl_programming_guide.docx differ diff --git a/doc/dpl_programming_guide.pdf b/doc/dpl_programming_guide.pdf new file mode 100644 index 0000000..474a40d Binary files /dev/null and b/doc/dpl_programming_guide.pdf differ diff --git a/etc/CMakeLists.txt b/etc/CMakeLists.txt new file mode 100644 index 0000000..f3436e6 --- /dev/null +++ b/etc/CMakeLists.txt @@ -0,0 +1,8 @@ + +SET(ETC_DIR ${PROJECT_SOURCE_DIR}/etc) + +INSTALL(FILES + ${ETC_DIR}/wrt_commons_reset_db.sh + ${ETC_DIR}/wrt_commons_create_clean_db.sh + DESTINATION /usr/bin + ) diff --git a/etc/DESCRIPTION b/etc/DESCRIPTION new file mode 100644 index 0000000..bf6eac9 --- /dev/null +++ b/etc/DESCRIPTION @@ -0,0 +1 @@ +This directory contain confiration scripts, config files, certificates and all other data that don't fit to other directories. diff --git a/etc/wrt_commons_create_clean_db.sh b/etc/wrt_commons_create_clean_db.sh new file mode 100755 index 0000000..d77048b --- /dev/null +++ b/etc/wrt_commons_create_clean_db.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +DB_PATH=/opt/dbspace/ +DB_USER_PATH=/opt/usr/dbspace/ + +function create_db { + name=$1 + dbpath=$2 + # extract smack label before removal + DB_LABEL="" + if [ -f $dbpath.$name.db ] + then + DB_LABEL=`/usr/bin/chsmack $dbpath.$name.db | sed -r "s/.*access=\"([^\"]+)\"/\1/"` + fi + /bin/rm -f $dbpath.$name.db + + # extract smack label before removal + JOURNAL_LABEL="" + if [ -f $dbpath.$name.db-journal ] + then + JOURNAL_LABEL=`/usr/bin/chsmack $dbpath.$name.db-journal | sed -r "s/.*access=\"([^\"]+)\"/\1/"` + fi + /bin/rm -f $dbpath.$name.db-journal + + SQL="PRAGMA journal_mode = PERSIST;" + /usr/bin/sqlite3 $dbpath.$name.db "$SQL" + SQL=".read /usr/share/wrt-engine/"$name"_db.sql" + /usr/bin/sqlite3 $dbpath.$name.db "$SQL" + /bin/touch $dbpath.$name.db-journal + /bin/chown 0:6026 $dbpath.$name.db + /bin/chown 0:6026 $dbpath.$name.db-journal + /bin/chmod 660 $dbpath.$name.db + /bin/chmod 660 $dbpath.$name.db-journal + + /usr/bin/pkill -9 security-serv + + # restore smack label + if [ -n "$DB_LABEL" ] + then + /usr/bin/chsmack -a "$DB_LABEL" $dbpath.$name.db + fi + + # restore smack label + if [ -n "$JOURNAL_LABEL" ] + then + /usr/bin/chsmack -a "$JOURNAL_LABEL" $dbpath.$name.db-journal + fi +} + +for name in wrt +do + create_db $name $DB_PATH +done + +for name in wrt_custom_handler wrt_i18n +do + create_db $name $DB_USER_PATH +done diff --git a/etc/wrt_commons_reset_db.sh b/etc/wrt_commons_reset_db.sh new file mode 100755 index 0000000..6d578c7 --- /dev/null +++ b/etc/wrt_commons_reset_db.sh @@ -0,0 +1,73 @@ +#!/bin/sh +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +/bin/rm -rf /opt/share/widget/system/* +uninstall_widgets=1 +if [ "$1" == "--old" ] +then + /bin/echo "Uninstalling turned off" + uninstall_widgets=0 +fi +#Removing of widget desktop icons +WIDGET_EXEC_PATH=/opt/usr/apps/ +WIDGET_PRELOAD_EXEC_PATH=/usr/apps/ +WIDGET_DESKTOP_PATH=/opt/share/applications/ +SMACK_RULES_PATH=/etc/smack/accesses.d/ +WRT_DB=/opt/dbspace/.wrt.db +PKGMGR_DB=/opt/dbspace/.pkgmgr_parser.db +PLUGINS_INSTALLATION_REQUIRED_PATH=/opt/share/widget/ +PLUGINS_INSTALLATION_REQUIRED=plugin-installation-required + +if [ -f ${WRT_DB} ] +then + PKG_NAME_SET=$(/usr/bin/sqlite3 $WRT_DB 'select tizen_appid from WidgetInfo;') + for appid in $PKG_NAME_SET + do + if [ $uninstall_widgets -eq 1 ] + then + wrt-installer -un $appid 1>/dev/null 2>&1 + fi + pkgId=`echo "$appid" | cut -f1 -d"."` + /usr/bin/sqlite3 $PKGMGR_DB "delete from package_info where package=\"$pkgId\"" + /usr/bin/sqlite3 $PKGMGR_DB "delete from package_app_info where app_id=\"$appid\"" + /bin/rm -rf ${WIDGET_EXEC_PATH}${pkgId} + /bin/rm -rf ${WIDGET_PRELOAD_EXEC_PATH}${pkgId} + widget_desktop_file="${WIDGET_DESKTOP_PATH}${appid}.desktop"; + if [ -f ${widget_desktop_file} ]; then + /bin/rm -f $widget_desktop_file; + fi + widget_smack_rule="${SMACK_RULES_PATH}${pkgId}" + if [ -f ${widget_smack_rule} ]; then + /bin/rm -f $widget_smack_rule; + fi + done +else + echo "${WRT_DB} doesn't exist" +fi + +/usr/bin/wrt_commons_create_clean_db.sh + +#TODO: remove this when switched to wrt-plugins-installer completely +if [ -e ${PLUGINS_INSTALLATION_REQUIRED_PATH} ] && [ -d ${PLUGINS_INSTALLATION_REQUIRED_PATH} ] +then + /bin/touch ${PLUGINS_INSTALLATION_REQUIRED_PATH}${PLUGINS_INSTALLATION_REQUIRED} +fi + +#update plugins +if [ -x /usr/bin/wrt-installer ] +then + /usr/bin/wrt-installer -p +fi diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..82e583f --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# + +# Check minimum CMake version +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# Project name +PROJECT(dpl-examples) + +# Set common compiler flags +ADD_DEFINITIONS("-Wall -Wextra -ansi -pedantic") + +# Add examples +ADD_SUBDIRECTORY(simple) +ADD_SUBDIRECTORY(rpc) +ADD_SUBDIRECTORY(fake_rpc) +ADD_SUBDIRECTORY(binary_queue) +ADD_SUBDIRECTORY(socket) +ADD_SUBDIRECTORY(tcpsock) +ADD_SUBDIRECTORY(timed_event) +ADD_SUBDIRECTORY(single_instance) +ADD_SUBDIRECTORY(crypto_hash) +ADD_SUBDIRECTORY(metronome) +ADD_SUBDIRECTORY(copy) diff --git a/examples/DESCRIPTION b/examples/DESCRIPTION new file mode 100644 index 0000000..db99a6d --- /dev/null +++ b/examples/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +Example code diff --git a/examples/binary_queue/CMakeLists.txt b/examples/binary_queue/CMakeLists.txt new file mode 100644 index 0000000..5fb9fee --- /dev/null +++ b/examples/binary_queue/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(BINARY_QUEUE_SYS dpl-gtk REQUIRED) + +SET(BINARY_QUEUE_SOURCES + binary_queue.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${BINARY_QUEUE_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${BINARY_QUEUE_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(binary_queue ${BINARY_QUEUE_SOURCES}) +TARGET_LINK_LIBRARIES(binary_queue ${BINARY_QUEUE_SYS_LIBRARIES}) diff --git a/examples/binary_queue/binary_queue.cpp b/examples/binary_queue/binary_queue.cpp new file mode 100644 index 0000000..063b6af --- /dev/null +++ b/examples/binary_queue/binary_queue.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file binary_queue.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of binary queue example + */ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + DPL::BinaryQueue queue; + Assert(queue.Size() == 0); + + for (int i=0; i<10; ++i) + { + int value = 12345; + queue.AppendCopy(&value, sizeof(value)); + queue.AppendUnmanaged(malloc(100), 100); + } + + Assert(queue.Size() == 10 * sizeof(int) + 10 * 100); + + for (size_t i = 0; i < 10 * sizeof(int) + 10 * 100; ++i) + { + char buffer[1]; + queue.Flatten(buffer, 1); + + queue.FlattenConsume(NULL, 0); + queue.Flatten(NULL, 0); + queue.FlattenConsume(buffer, 1); + } + +// UNHANDLED_EXCEPTION_HANDLER_BEGIN +// { +// char a; +// queue.FlattenConsume(&a, sizeof(a)); +// } +// UNHANDLED_EXCEPTION_HANDLER_END + + return 0; +} diff --git a/examples/copy/CMakeLists.txt b/examples/copy/CMakeLists.txt new file mode 100644 index 0000000..ace88df --- /dev/null +++ b/examples/copy/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(COPY_SYS dpl-gtk REQUIRED) + +SET(COPY_SOURCES + copy.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${COPY_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${COPY_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(copy ${COPY_SOURCES}) +TARGET_LINK_LIBRARIES(copy ${COPY_SYS_LIBRARIES}) diff --git a/examples/copy/copy.cpp b/examples/copy/copy.cpp new file mode 100644 index 0000000..5fa9484 --- /dev/null +++ b/examples/copy/copy.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file copy.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of copy example + */ +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc != 3 && argc != 4) + { + std::cout << "Invalid parameters: copy [input_file] [output_file] [OPTIONAL: number_of_bytes]" << std::endl; + return -1; + } + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + DPL::FileInput input(argv[1]); + DPL::FileOutput output(argv[2]); + + if (argc == 3) + DPL::Copy(&input, &output); + else + DPL::Copy(&input, &output, static_cast(atoi(argv[3]))); + } + UNHANDLED_EXCEPTION_HANDLER_END + + return 0; +} diff --git a/examples/crypto_hash/CMakeLists.txt b/examples/crypto_hash/CMakeLists.txt new file mode 100644 index 0000000..e0b0598 --- /dev/null +++ b/examples/crypto_hash/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(CRYPTO_HASH_SYS dpl-efl REQUIRED) + +SET(CRYPTO_HASH_SOURCES + crypto_hash.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${CRYPTO_HASH_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${CRYPTO_HASH_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(crypto_hash ${CRYPTO_HASH_SOURCES}) +TARGET_LINK_LIBRARIES(crypto_hash ${CRYPTO_HASH_SYS_LIBRARIES}) diff --git a/examples/crypto_hash/crypto_hash.cpp b/examples/crypto_hash/crypto_hash.cpp new file mode 100644 index 0000000..791b971 --- /dev/null +++ b/examples/crypto_hash/crypto_hash.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file crypto_hash.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of crypto hash example + */ +#include +#include +#include +#include + +void help() +{ + std::cout << "Invalid parameters: crypto_hash [hash_function] [message]" << std::endl; + std::cout << "hash_function is one of following: MD2, MD4, MD5, SHA, SHA1, DSS, DSS1, ECDSA, SHA224, SHA256, SHA384, SHA512" << std::endl; +} + +int main(int argc, char *argv[]) +{ + if (argc != 3) + { + help(); + return 0; + } + + DPL::Crypto::Hash::Base *crypto; + std::string algorithm = argv[1]; + + if (algorithm == "MD2") + crypto = new DPL::Crypto::Hash::MD2(); + else if (algorithm == "MD4") + crypto = new DPL::Crypto::Hash::MD4(); + else if (algorithm == "MD5") + crypto = new DPL::Crypto::Hash::MD5(); + else if (algorithm == "SHA") + crypto = new DPL::Crypto::Hash::SHA(); + else if (algorithm == "SHA1") + crypto = new DPL::Crypto::Hash::SHA1(); + else if (algorithm == "DSS") + crypto = new DPL::Crypto::Hash::DSS(); + else if (algorithm == "DSS1") + crypto = new DPL::Crypto::Hash::DSS1(); + else if (algorithm == "ECDSA") + crypto = new DPL::Crypto::Hash::ECDSA(); + else if (algorithm == "SHA224") + crypto = new DPL::Crypto::Hash::SHA224(); + else if (algorithm == "SHA256") + crypto = new DPL::Crypto::Hash::SHA256(); + else if (algorithm == "SHA384") + crypto = new DPL::Crypto::Hash::SHA384(); + else if (algorithm == "SHA512") + crypto = new DPL::Crypto::Hash::SHA512(); + else + { + help(); + return 0; + } + + crypto->Append(argv[2]); + crypto->Finish(); + + std::cout << crypto->ToString() << std::endl; + + delete crypto; + + return 0; +} diff --git a/examples/dbus/client-example/CMakeLists.txt b/examples/dbus/client-example/CMakeLists.txt new file mode 100644 index 0000000..1f9241f --- /dev/null +++ b/examples/dbus/client-example/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 2.6) +project(client-example) + +include(FindPkgConfig) + +pkg_check_modules(DEPS + dbus-1 + dpl-efl + dpl-dbus-efl + REQUIRED) + +set(TARGET_NAME "client-example") + +set(SRCS + client-example.cpp) + +include_directories(${DEPS_INCLUDE_DIRS}) + +add_definitions("-std=c++0x") +add_definitions("-DDPL_LOGS_ENABLED") + +add_executable(${TARGET_NAME} ${SRCS}) +target_link_libraries(${TARGET_NAME} ${DEPS_LIBRARIES}) + diff --git a/examples/dbus/client-example/client-example.cpp b/examples/dbus/client-example/client-example.cpp new file mode 100644 index 0000000..878febf --- /dev/null +++ b/examples/dbus/client-example/client-example.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file client-example.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Implementation for simple echo service DBus client. + */ +#include +#include +#include + +#include + +int main(int argc, char **argv) +{ + DPL::DBus::Client client("/path/to/object", + "org.tizen.EchoService", + "org.tizen.EchoInterface"); + std::string outstr; + client.Call("echo", "Samsung Rocks! Hello World Test!", &outstr); + std::cout << "Returned: " << outstr << std::endl; + exit(0); +} + diff --git a/examples/dbus/server-example/CMakeLists.txt b/examples/dbus/server-example/CMakeLists.txt new file mode 100644 index 0000000..34266e3 --- /dev/null +++ b/examples/dbus/server-example/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 2.6) +project(server-example) + +include(FindPkgConfig) + +pkg_check_modules(DEPS + glib-2.0 + gio-2.0 + dpl-efl + dpl-dbus-efl + REQUIRED) + +set(TARGET_NAME "server-example") + +set(SRCS + server-example.cpp) + +include_directories(${DEPS_INCLUDE_DIRS}) + +add_definitions("-std=c++0x") +add_definitions("-pedantic") +add_definitions("-Wall") +add_definitions("-DDPL_LOGS_ENABLED") + +add_executable(${TARGET_NAME} ${SRCS}) +target_link_libraries(${TARGET_NAME} ${DEPS_LIBRARIES}) \ No newline at end of file diff --git a/examples/dbus/server-example/server-example.cpp b/examples/dbus/server-example/server-example.cpp new file mode 100644 index 0000000..84e665d --- /dev/null +++ b/examples/dbus/server-example/server-example.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +std::string xml = +"" +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +""; + +GMainLoop* g_loop = NULL; + +auto g_interfaces = DPL::DBus::Interface::fromXMLString(xml); + +class DBusDispatcher : public DPL::DBus::Dispatcher +{ +public: + void onMethodCall(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *methodName, + GVariant *parameters, + GDBusMethodInvocation *invocation) + { + LogDebug("On method call: " << methodName); + + if (g_strcmp0(methodName, "echo") == 0) + { + const gchar* arg = NULL; + + g_variant_get(parameters, "(&s)", &arg); + LogDebug("Client said: " << arg); + + gchar* response = g_strdup_printf(arg); + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(s)", + response)); + g_free (response); + sleep(5); + } + else if (g_strcmp0(methodName, "quit") == 0) + { + g_main_loop_quit(g_loop); + } + } +}; + +class NewConnectionListener : + public DPL::EventListener +{ +protected: + void OnEventReceived(const DPL::DBus::ServerEvents::NewConnectionEvent& event) + { + m_connection = event.GetArg0(); + + auto quitInterface = g_interfaces.at(1); + quitInterface->setDispatcher(std::make_shared()); + m_quitObject = DBus::Object::create("/object/quit", quitInterface); + + m_connection->registerObject(m_quitObject); + } + +private: + DPL::DBus::ConnectionPtr m_connection; + DPL::DBus::ObjectPtr m_quitObject; +}; + +int main() +{ + g_type_init(); + + // --------------- echo + auto echoConnection = DPL::DBus::Connection::sessionBus(); + + auto echoInterface = g_interfaces.at(0); + echoInterface->setDispatcher(std::make_shared()); + + auto echoObject = DPL::DBus::Object::create("/object/echo", echoInterface); + + echoConnection->registerObject(echoObject); + + echoConnection->registerService("org.tizen.EchoService"); + + // --------------- quit + std::unique_ptr listener(new NewConnectionListener); + auto server = DPL::DBus::Server::create("unix:abstract=someaddr"); + server->AddListener(listener.get()); + server->start(); + + g_loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(g_loop); + g_main_loop_unref(g_loop); + + return 0; +} diff --git a/examples/fake_rpc/CMakeLists.txt b/examples/fake_rpc/CMakeLists.txt new file mode 100644 index 0000000..0778da7 --- /dev/null +++ b/examples/fake_rpc/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Pawel Sikorski (p.sikorski@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(FAKE_RPC_SYS dpl-efl REQUIRED) + +SET(FAKE_RPC_SOURCES + fake_rpc.cpp) + +ADD_DEFINITIONS("-D_DEBUG") +ADD_DEFINITIONS("-DDPL_LOGS_ENABLED") + +INCLUDE_DIRECTORIES(${FAKE_RPC_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${FAKE_RPC_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(fake_rpc ${FAKE_RPC_SOURCES}) +TARGET_LINK_LIBRARIES(fake_rpc ${FAKE_RPC_SYS_LIBRARIES}) diff --git a/examples/fake_rpc/fake_rpc.cpp b/examples/fake_rpc/fake_rpc.cpp new file mode 100644 index 0000000..bab1069 --- /dev/null +++ b/examples/fake_rpc/fake_rpc.cpp @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file rpc.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of RPC example + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// FLOW: +// 1st connection - UnixSockets +// 2nd connection - Fake +// client sends data via fake IPC +// server sends back this data via unix IPC. +// client compare sent and received data + +static const char *UNIX_RPC_NAME = "/tmp/unix_socket_rpc"; +static const char *FAKE_RPC_NAME = "/tmp/fake_rpc"; + +typedef DPL::AbstractRPCConnectionEvents::AsyncCallEvent AsyncCallEvent; +typedef DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent + ConnectionClosedEvent; +typedef DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent + ConnectionBrokenEvent; +typedef DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent + ConnectionEstablishedEvent; + +class MyThread + : public DPL::Thread, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::UnixSocketRPCClient m_rpcUnixClient; + DPL::FakeRpcClient m_rpcFakeClient; + int m_connections; + int m_sentData; + int m_receivedData; + + std::unique_ptr m_rpcUnixConnection; + std::unique_ptr m_rpcFakeConnection; + + virtual void OnEventReceived(const AsyncCallEvent &event) + { + LogDebug("CLIENT: AsyncCallEvent received"); + + event.GetArg0().ConsumeArg(m_receivedData); + LogDebug("CLIENT: Result from server: " << m_receivedData); + + if (m_receivedData != m_sentData) + LogError("Wrong data Received!"); + } + + virtual void OnEventReceived(const ConnectionEstablishedEvent &event) + { + if (dynamic_cast(event.GetArg1())){ + ++m_connections; + LogDebug("CLIENT: Acquiring new fake connection"); + m_rpcFakeConnection.reset(event.GetArg1()); + //this is not used on this side +// m_rpcFakeConnection->DPL::EventSupport::AddListener(this); + } + else{ + ++m_connections; + LogDebug("CLIENT: Acquiring new unix connection"); + m_rpcUnixConnection.reset(event.GetArg1()); + m_rpcUnixConnection->DPL::EventSupport::AddListener(this); + } + if(m_connections == 2){ + m_sentData = 1213; + // Emit RPC function call + DPL::RPCFunction proc; + proc.AppendArg(m_sentData); + LogDebug("CLIENT: Calling RPC function"); + m_rpcFakeConnection->AsyncCall(proc); + } + } + +public: + MyThread() : + m_rpcUnixClient(NULL), + m_rpcFakeClient(NULL), + m_connections(0), + m_sentData(0), + m_receivedData(0) + {} + + virtual ~MyThread() + { + // Always quit thread + Quit(); + } + + virtual int ThreadEntry() + { + m_connections = 0; + // Attach RPC listeners + LogDebug("CLIENT: Attaching connection established event"); + m_rpcUnixClient.DPL::EventSupport::AddListener(this); + m_rpcFakeClient.DPL::EventSupport::AddListener(this); + + // Open connection to server + LogDebug("CLIENT: Opening connection to RPC"); + m_rpcUnixClient.Open(UNIX_RPC_NAME); + m_rpcFakeClient.Open(FAKE_RPC_NAME); + + // Start message loop + LogDebug("CLIENT: Starting thread event loop"); + int ret = Exec(); + + if (m_rpcUnixConnection.get()){ + LogDebug("CLIENT: Removing Unix connection"); + m_rpcUnixConnection->DPL::EventSupport::RemoveListener(this); + m_rpcUnixConnection.reset(); + } + + LogDebug("CLIENT: Closing"); + + if (m_rpcFakeConnection.get()){ + LogDebug("CLIENT: Removing Fake connection"); + //this is not used on this side +// m_rpcFakeConnection->DPL::EventSupport::RemoveListener(this); + m_rpcFakeConnection.reset(); + } + + // Detach RPC client listener + LogDebug("CLIENT: Detaching connection established event"); + m_rpcUnixClient.DPL::EventSupport::RemoveListener(this); + m_rpcFakeClient.DPL::EventSupport::RemoveListener(this); + + // Close RPC + LogDebug("CLIENT: Closing RPC client"); + m_rpcUnixClient.CloseAll(); + m_rpcFakeClient.Close();//not needed + + // Done + return ret; + } +}; + +DECLARE_GENERIC_EVENT_0(QuitEvent) +DECLARE_GENERIC_EVENT_0(CloseThreadEvent) + +class MyApplication + : public DPL::Application, + private DPL::Controller::Type>, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::UnixSocketRPCServer m_rpcUnixServer; + DPL::FakeRpcServer m_rpcFakeServer; + + std::unique_ptr m_rpcUnixConnection; + std::unique_ptr m_rpcFakeConnection; + + MyThread m_thread; + + // Quit application event occurred + virtual void OnEventReceived(const QuitEvent &/*event*/){ + // Close RPC now + LogDebug("SERVER: Closing RPC connection..."); + + // Detach RPC connection listeners + if (m_rpcUnixConnection.get()) { + //this is not used on this side +// m_rpcUnixConnection->DPL::EventSupport::RemoveListener(this); + m_rpcUnixConnection.reset(); + } + + if (m_rpcFakeConnection.get()) { + m_rpcFakeConnection->DPL::EventSupport::RemoveListener(this); + m_rpcFakeConnection.reset(); + } + + LogDebug("SERVER: Closing Server"); + m_rpcUnixServer.CloseAll(); + m_rpcFakeServer.CloseAll();//not needed + m_rpcUnixServer.DPL::EventSupport::RemoveListener(this); + m_rpcFakeServer.DPL::EventSupport::RemoveListener(this); + + LogDebug("SERVER: Server closed"); + + Quit(); + } + + virtual void OnEventReceived(const CloseThreadEvent &/*event*/){ + m_thread.Quit(); + } + + virtual void OnEventReceived(const AsyncCallEvent &event) + { + LogDebug("SERVER: AsyncCallEvent received"); + + int value; + event.GetArg0().ConsumeArg(value); + LogDebug("SERVER: Result from client: " << value); + + // send back data to client (via fake) + // Emit RPC function call + DPL::RPCFunction proc; + proc.AppendArg(value); + LogDebug("SERVER: Calling RPC function"); + m_rpcUnixConnection->AsyncCall(proc); + } + + virtual void OnEventReceived(const ConnectionEstablishedEvent &event) + { + // Save connection pointer + if (dynamic_cast(event.GetArg1())){ + LogDebug("SERVER: Acquiring Fake RPC connection"); + m_rpcFakeConnection.reset(event.GetArg1()); + m_rpcFakeConnection->DPL::EventSupport::AddListener(this); + } + else{ + LogDebug("SERVER: Acquiring Unix RPC connection"); + m_rpcUnixConnection.reset(event.GetArg1()); + //this is not used on this side +// m_rpcUnixConnection->DPL::EventSupport::AddListener(this); + } + } + +public: + MyApplication(int argc, char **argv) + : Application(argc, argv, "rpc") + { + // Attach RPC server listeners + LogDebug("SERVER: Attaching connection established event"); + m_rpcUnixServer.DPL::EventSupport::AddListener(this); + m_rpcFakeServer.DPL::EventSupport::AddListener(this); + + // Self touch + LogDebug("SERVER: Touching controller"); + Touch(); + + // Open RPC server + LogDebug("SERVER: Opening server RPC"); + m_rpcUnixServer.Open(UNIX_RPC_NAME); + m_rpcFakeServer.Open(FAKE_RPC_NAME); + + // Run RPC client in thread + LogDebug("SERVER: Starting RPC client thread"); + m_thread.Run(); + + // Quit application automatically in few seconds + LogDebug("SERVER: Sending control timed events"); + DPL::ControllerEventHandler::PostTimedEvent(CloseThreadEvent(), 2); + DPL::ControllerEventHandler::PostTimedEvent(QuitEvent(), 3); + } + + virtual ~MyApplication() + { + // Quit thread + LogDebug("SERVER: Quitting thread"); + } +}; + +int main(int argc, char *argv[]) +{ + LogDebug("Starting"); + MyApplication app(argc, argv); + return app.Exec(); +} diff --git a/examples/metronome/CMakeLists.txt b/examples/metronome/CMakeLists.txt new file mode 100644 index 0000000..b5d1017 --- /dev/null +++ b/examples/metronome/CMakeLists.txt @@ -0,0 +1,38 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(METRONOME_SYS dpl-efl REQUIRED) + +SET(METRONOME_CLIENT_SOURCES + metronome_client.cpp) + +SET(METRONOME_SERVER_SOURCES + metronome_server.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${METRONOME_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${METRONOME_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(metronome_client ${METRONOME_CLIENT_SOURCES}) +TARGET_LINK_LIBRARIES(metronome_client ${METRONOME_SYS_LIBRARIES}) + +ADD_EXECUTABLE(metronome_server ${METRONOME_SERVER_SOURCES}) +TARGET_LINK_LIBRARIES(metronome_server ${METRONOME_SYS_LIBRARIES}) diff --git a/examples/metronome/metronome_client.cpp b/examples/metronome/metronome_client.cpp new file mode 100644 index 0000000..1fca0df --- /dev/null +++ b/examples/metronome/metronome_client.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file metronome_client.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of metronome client example + */ +#include +#include +#include +#include +#include + +class MetronomeClientApplication + : public DPL::Application, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::TcpSocketRPCClient m_rpcClient; + std::unique_ptr m_rpcConnection; + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::AsyncCallEvent &event) + { + (void)event; + + // Heart beat + LogDebug("* Got metronome signal *"); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event) + { + (void)event; + + LogDebug("Connection closed"); + + // Must quit + Quit(); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event) + { + (void)event; + + LogDebug("Connection broken"); + + // Must quit + Quit(); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent &event) + { + // Save connection pointer + LogDebug("Connected to metronome server"); + m_rpcConnection.reset(event.GetArg1()); + + // Attach event listeners + m_rpcConnection->DPL::EventSupport::AddListener(this); + m_rpcConnection->DPL::EventSupport::AddListener(this); + m_rpcConnection->DPL::EventSupport::AddListener(this); + } + +public: + MetronomeClientApplication(int argc, char **argv) + : Application(argc, argv, "rpc") + { + // Attach RPC server listeners + m_rpcClient.DPL::EventSupport::AddListener(this); + + // Open RPC server + m_rpcClient.Open("127.0.0.1", 12345); + + // Started + LogDebug("Metronome client started"); + } + + virtual ~MetronomeClientApplication() + { + // Delete all RPC connections + if (m_rpcConnection.get()) + { + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection.reset(); + } + + // Close RPC server + m_rpcClient.CloseAll(); + + // Detach RPC server listener + m_rpcClient.DPL::EventSupport::RemoveListener(this); + } +}; + +int main(int argc, char *argv[]) +{ + return MetronomeClientApplication(argc, argv).Exec(); +} diff --git a/examples/metronome/metronome_server.cpp b/examples/metronome/metronome_server.cpp new file mode 100644 index 0000000..cc0ad0a --- /dev/null +++ b/examples/metronome/metronome_server.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file metronome_server.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of metronome server example + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Metronome signal event +DECLARE_GENERIC_EVENT_0(SignalEvent) +DECLARE_GENERIC_EVENT_1(DeleteConnectionEvent, DPL::AbstractRPCConnection *) + +// Heart beat interval +const double HEART_BEAT_INTERVAL = 1.0; // seconds + +class MetronomeServerApplication + : public DPL::Application, + private DPL::Controller::Type>, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::TcpSocketRPCServer m_rpcServer; + + typedef std::list ConnectionList; + ConnectionList m_connections; + + // Matronome signal received + virtual void OnEventReceived(const SignalEvent &event) + { + (void)event; + + // Signal all conection about heart beat + DPL::RPCFunction proc; + proc.AppendArg((int)0); + + for (ConnectionList::iterator it = m_connections.begin(); it != m_connections.end(); ++it) + (*it)->AsyncCall(proc); + + // Continue to emot heart beats + DPL::ControllerEventHandler::PostTimedEvent(SignalEvent(), HEART_BEAT_INTERVAL); + } + + virtual void OnEventReceived(const DeleteConnectionEvent &event) + { + delete event.GetArg0(); + } + + void RemoveConnection(DPL::AbstractRPCConnection *connection) + { + // Find connection + ConnectionList::iterator it = std::find(m_connections.begin(), m_connections.end(), connection); + Assert(it != m_connections.end()); + + // Erase connection + m_connections.erase(it); + + // Detach RPC connection listeners + connection->DPL::EventSupport::RemoveListener(this); + connection->DPL::EventSupport::RemoveListener(this); + + // Delete connection + DPL::ControllerEventHandler::PostEvent(DeleteConnectionEvent(connection)); + } + + void AddConnection(DPL::AbstractRPCConnection *connection) + { + // Add connection + m_connections.push_back(connection); + + // Attach event listeners + connection->DPL::EventSupport::AddListener(this); + connection->DPL::EventSupport::AddListener(this); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event) + { + (void)event; + + LogDebug("Connection closed"); + + // Remove connection from list + RemoveConnection(static_cast(event.GetSender())); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event) + { + (void)event; + + LogDebug("Connection broken"); + + // Remove connection from list + RemoveConnection(static_cast(event.GetSender())); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent &event) + { + // Save connection pointer + LogDebug("New connection"); + + // Add nre connection to list + AddConnection(event.GetArg1()); + } + +public: + MetronomeServerApplication(int argc, char **argv) + : Application(argc, argv, "rpc") + { + // Attach RPC server listeners + m_rpcServer.DPL::EventSupport::AddListener(this); + + // Inherit calling context + Touch(); + + // Open RPC server + m_rpcServer.Open(12345); + + // Start heart beat + DPL::ControllerEventHandler::PostTimedEvent(SignalEvent(), HEART_BEAT_INTERVAL); + + // Started + LogDebug("Metronome server started"); + } + + virtual ~MetronomeServerApplication() + { + // Delete all RPC connections + while (!m_connections.empty()) + RemoveConnection(m_connections.front()); + + // Close RPC server + m_rpcServer.CloseAll(); + + // Detach RPC server listener + m_rpcServer.DPL::EventSupport::RemoveListener(this); + } +}; + +int main(int argc, char *argv[]) +{ + return MetronomeServerApplication(argc, argv).Exec(); +} diff --git a/examples/rpc/CMakeLists.txt b/examples/rpc/CMakeLists.txt new file mode 100644 index 0000000..d9c7d57 --- /dev/null +++ b/examples/rpc/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(RPC_SYS dpl-efl REQUIRED) + +SET(RPC_SOURCES + rpc.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${RPC_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${RPC_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(rpc ${RPC_SOURCES}) +TARGET_LINK_LIBRARIES(rpc ${RPC_SYS_LIBRARIES}) diff --git a/examples/rpc/rpc.cpp b/examples/rpc/rpc.cpp new file mode 100644 index 0000000..6991edb --- /dev/null +++ b/examples/rpc/rpc.cpp @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file rpc.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of RPC example + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *RPC_NAME = "/tmp/unix_socket_rpc"; + +class MyThread + : public DPL::Thread, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::UnixSocketRPCClient m_rpcClient; + std::unique_ptr m_rpcConnection; + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::AsyncCallEvent &event) + { + (void)event; + + LogDebug("CLIENT: AsyncCallEvent received"); + + int value; + event.GetArg0().ConsumeArg(value); + LogDebug("CLIENT: Result from server: " << value); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event) + { + (void)event; + LogDebug("CLIENT: ConnectionClosedEvent received"); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event) + { + (void)event; + LogDebug("CLIENT: ConnectionBrokenEvent received"); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent &event) + { + // Save connection pointer + LogDebug("CLIENT: Acquiring new connection"); + m_rpcConnection.reset(event.GetArg1()); + + // Attach listener to new connection + LogDebug("CLIENT: Attaching connection event listeners"); + m_rpcConnection->DPL::EventSupport::AddListener(this); + m_rpcConnection->DPL::EventSupport::AddListener(this); + m_rpcConnection->DPL::EventSupport::AddListener(this); + + LogDebug("CLIENT: Connection established"); + + // Emit RPC function call + DPL::RPCFunction proc; + proc.AppendArg((int)1111); + LogDebug("CLIENT: Calling RPC function"); + m_rpcConnection->AsyncCall(proc); + } + +public: + virtual ~MyThread() + { + // Always quit thread + Quit(); + } + + virtual int ThreadEntry() + { + // Attach RPC listeners + LogDebug("CLIENT: Attaching connection established event"); + m_rpcClient.DPL::EventSupport::AddListener(this); + + // Open connection to server + LogDebug("CLIENT: Opening connection to RPC"); + m_rpcClient.Open(RPC_NAME); + + // Start message loop + LogDebug("CLIENT: Starting thread event loop"); + int ret = Exec(); + + // Detach RPC listeners + if (m_rpcConnection.get()) + { + LogDebug("CLIENT: Detaching RPC connection events"); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + + LogDebug("CLIENT: Resetting connection"); + m_rpcConnection.reset(); + } + + // Detach RPC client listener + LogDebug("CLIENT: Detaching connection established event"); + m_rpcClient.DPL::EventSupport::RemoveListener(this); + + // Close RPC + LogDebug("CLIENT: Closing RPC client"); + m_rpcClient.CloseAll(); + + // Done + return ret; + } +}; + +DECLARE_GENERIC_EVENT_0(QuitEvent) +DECLARE_GENERIC_EVENT_0(CloseThreadEvent) + +class MyApplication + : public DPL::Application, + private DPL::Controller::Type>, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::UnixSocketRPCServer m_rpcServer; + std::unique_ptr m_rpcConnection; + + MyThread m_thread; + + // Quit application event occurred + virtual void OnEventReceived(const QuitEvent &event) + { + (void)event; + Quit(); + } + + virtual void OnEventReceived(const CloseThreadEvent &event) + { + (void)event; + m_thread.Quit(); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::AsyncCallEvent &event) + { + (void)event; + + LogDebug("SERVER: AsyncCallEvent received"); + + int value; + event.GetArg0().ConsumeArg(value); + LogDebug("SERVER: Result from client: " << value); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event) + { + (void)event; + + LogDebug("SERVER: ConnectionClosedEvent received"); + + // Close RPC now + LogDebug("SERVER: Closing RPC connection on event..."); + + // Detach RPC connection listeners + if (m_rpcConnection.get()) + { + LogDebug("SERVER: Detaching connection events"); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + m_rpcConnection->DPL::EventSupport::RemoveListener(this); + } + LogDebug("SERVER: RPC connection closed"); + + LogDebug("SERVER: Closing RPC on event..."); + m_rpcServer.CloseAll(); + LogDebug("SERVER: RPC closed"); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event) + { + (void)event; + LogDebug("SERVER: ConnectionBrokenEvent received"); + } + + virtual void OnEventReceived(const DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent &event) + { + // Save connection pointer + LogDebug("SERVER: Acquiring RPC connection"); + m_rpcConnection.reset(event.GetArg1()); + + // Attach event listeners + LogDebug("SERVER: Attaching connection listeners"); + m_rpcConnection->DPL::EventSupport::AddListener(this); + m_rpcConnection->DPL::EventSupport::AddListener(this); + m_rpcConnection->DPL::EventSupport::AddListener(this); + + LogDebug("SERVER: Connection established"); + + // Emit RPC function call + DPL::RPCFunction proc; + proc.AppendArg((int)2222); + LogDebug("SERVER: Calling RPC function"); + m_rpcConnection->AsyncCall(proc); + } + +public: + MyApplication(int argc, char **argv) + : Application(argc, argv, "rpc") + { + // Attach RPC server listeners + LogDebug("SERVER: Attaching connection established event"); + m_rpcServer.DPL::EventSupport::AddListener(this); + + // Self touch + LogDebug("SERVER: Touching controller"); + Touch(); + + // Open RPC server + LogDebug("SERVER: Opening server RPC"); + m_rpcServer.Open(RPC_NAME); + + // Run RPC client in thread + LogDebug("SERVER: Starting RPC client thread"); + m_thread.Run(); + + // Quit application automatically in few seconds + LogDebug("SERVER: Sending control timed events"); + DPL::ControllerEventHandler::PostTimedEvent(CloseThreadEvent(), 2); + DPL::ControllerEventHandler::PostTimedEvent(QuitEvent(), 3); + } + + virtual ~MyApplication() + { + // Quit thread + LogDebug("SERVER: Quitting thread"); + m_thread.Quit(); + + // Close RPC server + LogDebug("SERVER: Closing RPC server"); + m_rpcServer.CloseAll(); + + // Detach RPC server listener + m_rpcServer.DPL::EventSupport::RemoveListener(this); + } +}; + +int main(int argc, char *argv[]) +{ + LogDebug("Starting"); + MyApplication app(argc, argv); + return app.Exec(); +} diff --git a/examples/simple/CMakeLists.txt b/examples/simple/CMakeLists.txt new file mode 100644 index 0000000..42020ec --- /dev/null +++ b/examples/simple/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SIMPLE_SYS dpl-gtk REQUIRED) + +SET(SIMPLE_SOURCES + simple.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${SIMPLE_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${SIMPLE_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(simple ${SIMPLE_SOURCES}) +TARGET_LINK_LIBRARIES(simple ${SIMPLE_SYS_LIBRARIES}) diff --git a/examples/simple/simple.cpp b/examples/simple/simple.cpp new file mode 100644 index 0000000..2ed9fab --- /dev/null +++ b/examples/simple/simple.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file simple.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of simple example + */ +#include +#include + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + LogDebug("Hello world!"); + return 0; +} + diff --git a/examples/single_instance/CMakeLists.txt b/examples/single_instance/CMakeLists.txt new file mode 100644 index 0000000..3c29cc6 --- /dev/null +++ b/examples/single_instance/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(RPC_SYS dpl-efl REQUIRED) + +SET(RPC_SOURCES + single_instance.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${RPC_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${RPC_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(single_instance ${RPC_SOURCES}) +TARGET_LINK_LIBRARIES(single_instance ${RPC_SYS_LIBRARIES}) diff --git a/examples/single_instance/single_instance.cpp b/examples/single_instance/single_instance.cpp new file mode 100644 index 0000000..038594b --- /dev/null +++ b/examples/single_instance/single_instance.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file single_instance.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of single instance example + */ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc != 2) + { + std::cout << "Specify instance name!" << std::endl; + return 0; + } + + DPL::SingleInstance singleInstance; + + if (singleInstance.TryLock(argv[1])) + { + std::cout << "Succedded to lock single instance." << std::endl << "Press ENTER to release lock..." << std::endl; + + // Wait for any key + getchar(); + + // Release gathered lock + singleInstance.Release(); + + // Done + return 0; + } + + std::cout << "Cannot retrieve single instance lock." << std::endl + << "Another application has locked single instance." << std::endl + << "Will now exit." << std::endl; + + // Done + return 0; +} diff --git a/examples/socket/CMakeLists.txt b/examples/socket/CMakeLists.txt new file mode 100644 index 0000000..9fe5009 --- /dev/null +++ b/examples/socket/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SOCKET_SYS dpl-efl REQUIRED) + +SET(SOCKET_SOURCES + socket.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${SOCKET_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${SOCKET_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(socket ${SOCKET_SOURCES}) +TARGET_LINK_LIBRARIES(socket ${SOCKET_SYS_LIBRARIES}) diff --git a/examples/socket/socket.cpp b/examples/socket/socket.cpp new file mode 100644 index 0000000..fc42632 --- /dev/null +++ b/examples/socket/socket.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file socket.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of socket example + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace // anonymous +{ +static const char *SOCKET_NAME = "/tmp/unix_sock"; +} // namespace anonymous + +class MyThread + : public DPL::Thread, + private DPL::EventListener +{ +private: + DPL::UnixSocket m_socket; + + // Socket accept event + virtual void OnEventReceived(const DPL::AbstractSocketEvents::AcceptEvent &event) + { + (void)event; + LogDebug("Accept event occurred"); + + DPL::UnixSocket *client = static_cast(m_socket.Accept()); + + LogDebug("Accepted client remote address: " << client->GetRemoteAddress().ToString()); + LogDebug("Accepted client local address: " << client->GetLocalAddress().ToString()); + + delete client; + } + +public: + virtual ~MyThread() + { + // Quit thread + Quit(); + } + + virtual int ThreadEntry() + { + // Add listeners + m_socket.DPL::EventSupport::AddListener(this); + + // Create server + LogDebug("Starting server..."); + + m_socket.Bind(DPL::Address(SOCKET_NAME)); + m_socket.Listen(5); + + LogDebug("Server started"); + + LogDebug("Server local address: " << m_socket.GetLocalAddress().ToString()); + + int result = Exec(); + + // Remove listeners + m_socket.DPL::EventSupport::RemoveListener(this); + + // Must close socket in same context + m_socket.Close(); + + return result; + } +}; + +DECLARE_GENERIC_EVENT_0(QuitEvent) + +class MyApplication + : public DPL::Application, + public DPL::Controller::Type>, + private DPL::EventListener +{ +private: + MyThread thread; + DPL::UnixSocket sock; + + // Quit application event occurred + virtual void OnEventReceived(const QuitEvent &event) + { + (void)event; + Quit(); + } + + // Socket connected event + virtual void OnEventReceived(const DPL::AbstractSocketEvents::ConnectedEvent &event) + { + (void)event; + LogDebug("Connected event occurred"); + } + +public: + MyApplication(int argc, char **argv) + : Application(argc, argv, "example_socket_application") + { + // Add listeners + sock.DPL::EventSupport::AddListener(this); + + // Touch self controller + Touch(); + + // Start threaded server + LogDebug("Running threaded server"); + + // Run server in thread + thread.Run(); + + LogDebug("Waiting for server to start..."); + sleep(1); + + // Connect to server + sock.Connect(DPL::Address(SOCKET_NAME)); + + // Quit application automatically in few seconds + DPL::ControllerEventHandler::PostTimedEvent(QuitEvent(), 2); + } + + virtual ~MyApplication() + { + // Remove listeners + sock.DPL::EventSupport::RemoveListener(this); + } +}; + +int main(int argc, char *argv[]) +{ + MyApplication app(argc, argv); + return app.Exec(); +} diff --git a/examples/tcpsock/CMakeLists.txt b/examples/tcpsock/CMakeLists.txt new file mode 100644 index 0000000..a6550fc --- /dev/null +++ b/examples/tcpsock/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(TCPSOCK_SYS dpl-efl REQUIRED) + +SET(TCPSOCK_SOURCES + tcpsock.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${TCPSOCK_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${TCPSOCK_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(tcpsock ${TCPSOCK_SOURCES}) +TARGET_LINK_LIBRARIES(tcpsock ${TCPSOCK_SYS_LIBRARIES}) diff --git a/examples/tcpsock/tcpsock.cpp b/examples/tcpsock/tcpsock.cpp new file mode 100644 index 0000000..57141ca --- /dev/null +++ b/examples/tcpsock/tcpsock.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file tcpsock.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of tcpsock example + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MyApplication + : public DPL::Application, + private DPL::EventListener, + private DPL::EventListener +{ +private: + DPL::TcpSocket m_socket; + + virtual void OnEventReceived(const DPL::AbstractSocketEvents::ConnectedEvent &event) + { + (void)event; + LogDebug("Connected!"); + + // Send request + DPL::BinaryQueue data; + const char *query = "GET /wiki/Main_Page HTTP/1.1\nHost: en.wikipedia.org\n\n"; + data.AppendCopy(query, strlen(query) + 1); + m_socket.Write(data, data.Size()); + } + + virtual void OnEventReceived(const DPL::AbstractSocketEvents::ReadEvent &event) + { + (void)event; + LogDebug("Read!"); + + DPL::BinaryQueueAutoPtr data = m_socket.Read(100); // Bad: DLOG cannot log more than about 450 bytes... + + Assert(data.get() != NULL); + + if (data->Empty()) + { + LogDebug("Connection closed!"); + m_socket.Close(); + + // Done + Quit(); + return; + } + + // Show data + DPL::ScopedArray text(new char[data->Size()]); + data->Flatten(text.Get(), data->Size()); + + LogPedantic("READ: \n--------------------------------------------------------\n" + << std::string(text.Get(), text.Get() + data->Size()) << + "\n--------------------------------------------------------"); + } + +public: + MyApplication(int argc, char **argv) + : Application(argc, argv, "tcpsock") + { + LogDebug("CTOR!"); + + // Add listeners + m_socket.DPL::EventSupport::AddListener(this); + m_socket.DPL::EventSupport::AddListener(this); + + // Connect + m_socket.Open(); + LogDebug("Connecting..."); + m_socket.Connect(DPL::Address("en.wikipedia.org", 80)); + } + + virtual ~MyApplication() + { + LogDebug("DTOR!"); + + // Remove listeners + m_socket.DPL::EventSupport::RemoveListener(this); + m_socket.DPL::EventSupport::RemoveListener(this); + } +}; + +int main(int argc, char *argv[]) +{ + MyApplication app(argc, argv); + return app.Exec(); +} diff --git a/examples/timed_event/CMakeLists.txt b/examples/timed_event/CMakeLists.txt new file mode 100644 index 0000000..cb60fb0 --- /dev/null +++ b/examples/timed_event/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) +# @version 1.0 +# @brief +# +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(RPC_SYS dpl-efl REQUIRED) + +SET(RPC_SOURCES + timed_event.cpp) + +ADD_DEFINITIONS("-D_DEBUG") + +INCLUDE_DIRECTORIES(${RPC_SYS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${RPC_SYS_LIBRARY_DIRS}) + +ADD_EXECUTABLE(timed_event ${RPC_SOURCES}) +TARGET_LINK_LIBRARIES(timed_event ${RPC_SYS_LIBRARIES}) diff --git a/examples/timed_event/timed_event.cpp b/examples/timed_event/timed_event.cpp new file mode 100644 index 0000000..f3d8e80 --- /dev/null +++ b/examples/timed_event/timed_event.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file timed_event.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of timed event example + */ +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GENERIC_EVENT_0(FirstEvent) +DECLARE_GENERIC_EVENT_0(SecondEvent) + +class ControllerInThread + : public DPL::Controller::Type> +{ +protected: + virtual void OnEventReceived(const FirstEvent &event) + { + (void)event; + LogDebug("First event occurred"); + } + + virtual void OnEventReceived(const SecondEvent &event) + { + (void)event; + LogDebug("Second event occurred"); + } +}; + +DECLARE_GENERIC_EVENT_0(QuitEvent) + +class MyApplication + : public DPL::Application, + private DPL::Controller::Type> +{ +private: + DPL::Thread m_thread; + ControllerInThread m_controllerInThread; + + // Quit application event occurred + virtual void OnEventReceived(const QuitEvent &event) + { + (void)event; + Quit(); + } + +public: + MyApplication(int argc, char **argv) + : Application(argc, argv, "timed_event", false) + { + // Touch + Touch(); + m_controllerInThread.Touch(); + + // Run thread + m_thread.Run(); + m_controllerInThread.SwitchToThread(&m_thread); + + // Emit thread timed events + m_controllerInThread.DPL::ControllerEventHandler::PostTimedEvent(SecondEvent(), 3); + m_controllerInThread.DPL::ControllerEventHandler::PostTimedEvent(FirstEvent(), 2); + + // Emit framework timed quit event + DPL::ControllerEventHandler::PostTimedEvent(QuitEvent(), 5); + } + + virtual ~MyApplication() + { + m_controllerInThread.SwitchToThread(NULL); + + // Quit thread + m_thread.Quit(); + } +}; + +int main(int argc, char *argv[]) +{ + MyApplication app(argc, argv); + return app.Exec(); +} diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt new file mode 100644 index 0000000..07c4c05 --- /dev/null +++ b/modules/CMakeLists.txt @@ -0,0 +1,38 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +include(core/config.cmake) +include(dbus/config.cmake) +include(db/config.cmake) +include(event/config.cmake) +include(socket/config.cmake) +include(rpc/config.cmake) +include(test/config.cmake) +include(log/config.cmake) +ADD_SUBDIRECTORY(widget_dao) +ADD_SUBDIRECTORY(widget_interface_dao) +ADD_SUBDIRECTORY(security_origin_dao) +ADD_SUBDIRECTORY(custom_handler_dao) +ADD_SUBDIRECTORY(certificate_dao) +ADD_SUBDIRECTORY(i18n) +include(utils/config.cmake) +include(localization/config.cmake) +include(support/config.cmake) diff --git a/modules/certificate_dao/CMakeLists.txt b/modules/certificate_dao/CMakeLists.txt new file mode 100755 index 0000000..f55ee45 --- /dev/null +++ b/modules/certificate_dao/CMakeLists.txt @@ -0,0 +1,57 @@ +SET(TARGET_CERTIFICATE_DAO_DB "Sqlite3DbCertificate") + +ADD_CUSTOM_COMMAND( OUTPUT .certificate.db + COMMAND rm -f ${CMAKE_CURRENT_BINARY_DIR}/.certificate.db + COMMAND gcc -Wall -I${PROJECT_SOURCE_DIR}/modules/db/include -I${PROJECT_SOURCE_DIR}/modules/certificate_dao/orm -E ${PROJECT_SOURCE_DIR}/modules/certificate_dao/orm/certificate_db_sql_generator.h | grep --invert-match "^#" > ${CMAKE_CURRENT_BINARY_DIR}/certificate_db.sql + COMMAND sqlite3 ${CMAKE_CURRENT_BINARY_DIR}/.certificate.db ".read ${CMAKE_CURRENT_BINARY_DIR}/certificate_db.sql" || rm -f ${CMAKE_CURRENT_BINARY_DIR}/.certificate.db + DEPENDS ${PROJECT_SOURCE_DIR}/modules/certificate_dao/orm/certificate_db_sql_generator.h ${PROJECT_SOURCE_DIR}/modules/certificate_dao/orm/certificate_db + ) + +ADD_CUSTOM_COMMAND( OUTPUT .certificate.db-journal + COMMAND touch + ARGS ${CMAKE_CURRENT_BINARY_DIR}/.certificate.db-journal + ) + +ADD_CUSTOM_TARGET(${TARGET_CERTIFICATE_DAO_DB} ALL DEPENDS .certificate.db .certificate.db-journal) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/certificate_db.sql DESTINATION share/wrt-engine/) + +############################################################################### + +INCLUDE(FindPkgConfig) + +PKG_CHECK_MODULES(CERTIFICATE_DAO_DEPS + glib-2.0 + REQUIRED) + +SET(CERTIFICATE_DAO_INCLUDE_DIRS + ${PROJECT_SOURCE_DIR}/modules/certificate_dao/include + ${PROJECT_SOURCE_DIR}/modules/certificate_dao/orm + ${PROJECT_SOURCE_DIR}/modules/core/include + ${PROJECT_SOURCE_DIR}/modules/db/include + ${PROJECT_SOURCE_DIR}/modules/log/include + ${PROJECT_SOURCE_DIR}/modules/widget_dao/include +) + +SET(CERTIFICATE_DAO_SOURCES + dao/certificate_dao_types.cpp + dao/certificate_dao.cpp + dao/certificate_database.cpp +) + +INCLUDE_DIRECTORIES(SYSTEM ${CERTIFICATE_DAO_DEPS_INCLUDE_DIRS} ) +INCLUDE_DIRECTORIES(${CERTIFICATE_DAO_INCLUDE_DIRS}) + +ADD_LIBRARY(${TARGET_CERTIFICATE_DAO_LIB} SHARED ${CERTIFICATE_DAO_SOURCES}) +SET_TARGET_PROPERTIES(${TARGET_CERTIFICATE_DAO_LIB} PROPERTIES SOVERSION ${API_VERSION} VERSION ${VERSION}) +TARGET_LINK_LIBRARIES(${TARGET_CERTIFICATE_DAO_LIB} ${TARGET_DPL_EFL} ${TARGET_DPL_DB_EFL} ${TARGET_WRT_DAP_RO_LIB} ${CERTIFICATE_DAO_DEPS_LIBRARIES}) +ADD_DEPENDENCIES(${TARGET_CERTIFICATE_DAO_LIB} ${TARGET_CERTIFICATE_DAO_DB}) + +INSTALL(TARGETS ${TARGET_CERTIFICATE_DAO_LIB} DESTINATION lib) + +INSTALL(FILES + include/wrt-commons/certificate-dao/certificate_dao_types.h + include/wrt-commons/certificate-dao/certificate_database.h + include/wrt-commons/certificate-dao/certificate_dao.h + DESTINATION include/dpl-efl/wrt-commons/certificate-dao +) + diff --git a/modules/certificate_dao/dao/certificate_dao.cpp b/modules/certificate_dao/dao/certificate_dao.cpp new file mode 100644 index 0000000..0d2138f --- /dev/null +++ b/modules/certificate_dao/dao/certificate_dao.cpp @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file certificate_dao.cpp + * @author Leerang Song (leerang.song@samsung.com) + * @version 1.0 + * @brief This file contains the definition of certificate dao class. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* GCC versions 4.7 had changes to the C++ standard. It + * no longer includes to remove namespace pollution. + */ +#include + +using namespace DPL::DB::ORM; +using namespace DPL::DB::ORM::certificate; + +namespace CertificateDB { +#define SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN Try + +#define SQL_CONNECTION_EXCEPTION_HANDLER_END(message) \ + Catch(DPL::DB::SqlConnection::Exception::Base) { \ + LogError(message); \ + ReThrowMsg(CertificateDAO::Exception::DatabaseError, \ + message); \ + } + +namespace { +DPL::DB::SqlConnection::Flag::Option CERTIFICATE_DB_OPTION = + DPL::DB::SqlConnection::Flag::RW; +DPL::DB::SqlConnection::Flag::Type CERTIFICATE_DB_TYPE = + DPL::DB::SqlConnection::Flag::UseLucene; +const char* const CERTIFICATE_DB_NAME = ".certificate.db"; +const char* const CERTIFICATE_DB_SQL_PATH = + "/usr/share/wrt-engine/certificate_db.sql"; +const char* const CERTIFICATE_DATABASE_JOURNAL_FILENAME = "-journal"; + +const int WEB_APPLICATION_UID = 5000; +const int WEB_APPLICATION_GUID = 5000; + +std::string createDatabasePath(const WrtDB::TizenPkgId &pkgName) +{ + std::stringstream filename; + + filename << WrtDB::WidgetConfig::GetWidgetPersistentStoragePath(pkgName) + << "/" + << CERTIFICATE_DB_NAME; + return filename.str(); +} + +void checkDatabase(std::string databasePath) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + if (databasePath.empty()) { + ThrowMsg(CertificateDAO::Exception::DatabaseError, + "Wrong database Path is passed"); + } + + struct stat buffer; + if (stat(databasePath.c_str(), &buffer) != 0) { + //Create fresh database + LogDebug("Creating database " << databasePath); + + std::fstream file; + file.open(CERTIFICATE_DB_SQL_PATH, std::ios_base::in); + if (!file) { + ThrowMsg(CertificateDAO::Exception::DatabaseError, + "Fail to get database schema from: " << CERTIFICATE_DB_SQL_PATH); + } + + std::stringstream ssBuffer; + ssBuffer << file.rdbuf(); + + file.close(); + + DPL::DB::SqlConnection con(databasePath, + CERTIFICATE_DB_TYPE, + CERTIFICATE_DB_OPTION); + con.ExecCommand(ssBuffer.str().c_str()); + } + + if(chown(databasePath.c_str(), + WEB_APPLICATION_UID, + WEB_APPLICATION_GUID) != 0) + { + ThrowMsg(CertificateDAO::Exception::DatabaseError, + "Fail to change uid/guid"); + } + std::string databaseJournal = + databasePath + CERTIFICATE_DATABASE_JOURNAL_FILENAME; + if(chown(databaseJournal.c_str(), + WEB_APPLICATION_UID, + WEB_APPLICATION_GUID) != 0) + { + ThrowMsg(CertificateDAO::Exception::DatabaseError, + "Fail to change uid/guid"); + } + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to get database Path") +} +} + +CertificateDAO::CertificateDAO(const WrtDB::TizenPkgId &pkgName) : + m_certificateDBPath(createDatabasePath(pkgName)), + m_certificateDBInterface(m_certificateDBPath, CERTIFICATE_DB_TYPE) +{ + checkDatabase(m_certificateDBPath); + m_certificateDBInterface.AttachToThread(CERTIFICATE_DB_OPTION); +} + +CertificateDAO::~CertificateDAO() +{ + m_certificateDBInterface.DetachFromThread(); +} + +CertificateDataList CertificateDAO::getCertificateDataList(void) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + CertificateDataList list; + CERTIFICATE_DB_SELECT(select, + CertificateInfo, + &m_certificateDBInterface); + typedef std::list RowList; + RowList rowList = select->GetRowList(); + + FOREACH(it, rowList) { + list.push_back( + CertificateDataPtr( + new CertificateData(it->Get_certificate()))); + } + return list; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get data list") +} + +Result CertificateDAO::getResult( + const CertificateData &certificateData) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + CERTIFICATE_DB_SELECT(select, + CertificateInfo, + &m_certificateDBInterface); + select->Where( + Equals(certificateData.certificate)); + CertificateInfo::Select::RowList rows = select->GetRowList(); + + if (rows.empty()) { + return RESULT_UNKNOWN; + } + CertificateInfo::Row row = rows.front(); + return static_cast(row.Get_result()); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END( + "Failed to get result for security certiInfo") +} + +void CertificateDAO::setCertificateData(const CertificateData &certificateData, + const Result result) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + ScopedTransaction transaction(&m_certificateDBInterface); + CertificateInfo::Row row; + row.Set_certificate(certificateData.certificate); + row.Set_result(result); + + if (true == hasResult(certificateData)) { + CERTIFICATE_DB_UPDATE(update, + CertificateInfo, + &m_certificateDBInterface); + update->Values(row); + update->Execute(); + } else { + CERTIFICATE_DB_INSERT(insert, + CertificateInfo, + &m_certificateDBInterface); + insert->Values(row); + insert->Execute(); + } + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to set security certiInfo data") +} + +void CertificateDAO::removeCertificateData( + const CertificateData &certificateData) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + ScopedTransaction transaction(&m_certificateDBInterface); + + if (true == hasResult(certificateData)) { + CERTIFICATE_DB_DELETE(del, + CertificateInfo, + &m_certificateDBInterface) + del->Where( + Equals(certificateData.certificate)); + del->Execute(); + transaction.Commit(); + } + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to set certiInfo data") +} + +void CertificateDAO::removeCertificateData(const Result result) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + ScopedTransaction transaction(&m_certificateDBInterface); + CERTIFICATE_DB_DELETE(del, + CertificateInfo, + &m_certificateDBInterface) + del->Where(Equals(result)); + del->Execute(); + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to remove data by result") +} + +bool CertificateDAO::hasResult(const CertificateData &certificateData) +{ + Result res = getResult(certificateData); + return (res != RESULT_UNKNOWN); +} + +#undef SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN +#undef SQL_CONNECTION_EXCEPTION_HANDLER_END +} // namespace CertificateDB diff --git a/modules/certificate_dao/dao/certificate_dao_types.cpp b/modules/certificate_dao/dao/certificate_dao_types.cpp new file mode 100755 index 0000000..35e8a58 --- /dev/null +++ b/modules/certificate_dao/dao/certificate_dao_types.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file certificate_dao_types.cpp + * @author Leerang Song (leerang.song@samsung.com) + * @version 1.0 + * @brief This file contains the implementation of + * common data types for certificate.db + */ + +#include +#include + +namespace CertificateDB { + +} // namespace CertificateDB diff --git a/modules/certificate_dao/dao/certificate_database.cpp b/modules/certificate_dao/dao/certificate_database.cpp new file mode 100755 index 0000000..4392e0c --- /dev/null +++ b/modules/certificate_dao/dao/certificate_database.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +DPL::Mutex g_certificateDBQueriesMutex; diff --git a/modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_dao.h b/modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_dao.h new file mode 100644 index 0000000..26e981b --- /dev/null +++ b/modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_dao.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file certificate_dao.h + * @author Leerang Song (leerang.song@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of certificate dao + */ +#ifndef _CERTIFICATE_DAO_H_ +#define _CERTIFICATE_DAO_H_ + +#include +#include +#include + +namespace CertificateDB { +class CertificateDAO +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DatabaseError) + DECLARE_EXCEPTION_TYPE(Base, DataNotExist) + }; + + explicit CertificateDAO(const WrtDB::TizenPkgId &pkgName); + virtual ~CertificateDAO(); + CertificateDataList getCertificateDataList(); + Result getResult(const CertificateData &certificateData); + void setCertificateData(const CertificateData &certificateData, + const Result result); + void removeCertificateData(const CertificateData &certificateData); + void removeCertificateData(const Result result); + + private: + std::string m_certificateDBPath; + DPL::DB::ThreadDatabaseSupport m_certificateDBInterface; + bool hasResult(const CertificateData &certificateData); +}; + +typedef std::shared_ptr CertificateDAOPtr; +} // namespace CertificateDB + +#endif // _CERTIFICATE_DAO_H_ \ No newline at end of file diff --git a/modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_dao_types.h b/modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_dao_types.h new file mode 100755 index 0000000..f059f4c --- /dev/null +++ b/modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_dao_types.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file certificate_dao_types.h + * @author Leerang Song (leerang.song@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of + * common data types for certificate database. + */ +#ifndef _CERTIFICATE_DAO_TYPES_H_ +#define _CERTIFICATE_DAO_TYPES_H_ + +#include +#include +#include + +namespace CertificateDB { + +enum Result +{ + RESULT_UNKNOWN = 0, + RESULT_ALLOW_ONCE, + RESULT_DENY_ONCE, + RESULT_ALLOW_ALWAYS, + RESULT_DENY_ALWAYS +}; + +struct CertificateData +{ + DPL::String certificate; + + CertificateData(const DPL::String& certi) : + certificate(certi) + {} + + bool operator== (const CertificateData& other) const + { + return (certificate == other.certificate); + } + + bool operator!= (const CertificateData& other) const + { + return !(*this == other); + } +}; + +typedef std::shared_ptr CertificateDataPtr; +typedef std::list CertificateDataList; +} // namespace CertificateDB + +#endif // _CERTIFICATE_DAO_TYPES_H_ \ No newline at end of file diff --git a/modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_database.h b/modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_database.h new file mode 100755 index 0000000..f0ee954 --- /dev/null +++ b/modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_database.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CERTIFICATE_DATABASE_H_ +#define _CERTIFICATE_DATABASE_H_ + +#include +#include + +extern DPL::Mutex g_certificateDBQueriesMutex; + +#define CERTIFICATE_DB_INTERNAL(tlsCommand, InternalType, interface) \ + static DPL::ThreadLocalVariable *tlsCommand##Ptr = NULL; \ + { \ + DPL::Mutex::ScopedLock lock(&g_certificateDBQueriesMutex); \ + if (!tlsCommand##Ptr) { \ + static DPL::ThreadLocalVariable tmp; \ + tlsCommand##Ptr = &tmp; \ + } \ + } \ + DPL::ThreadLocalVariable &tlsCommand = *tlsCommand##Ptr; \ + if (tlsCommand.IsNull()) { tlsCommand = InternalType(interface); } + +#define CERTIFICATE_DB_SELECT(name, type, interface) \ + CERTIFICATE_DB_INTERNAL(name, type::Select, interface) + +#define CERTIFICATE_DB_INSERT(name, type, interface) \ + CERTIFICATE_DB_INTERNAL(name, type::Insert, interface) + +#define CERTIFICATE_DB_UPDATE(name, type, interface) \ + CERTIFICATE_DB_INTERNAL(name, type::Update, interface) + +#define CERTIFICATE_DB_DELETE(name, type, interface) \ + CERTIFICATE_DB_INTERNAL(name, type::Delete, interface) + +#endif // _CERTIFICATE_DATABASE_H_ + diff --git a/modules/certificate_dao/orm/certificate_db b/modules/certificate_dao/orm/certificate_db new file mode 100755 index 0000000..2dbe366 --- /dev/null +++ b/modules/certificate_dao/orm/certificate_db @@ -0,0 +1,9 @@ +SQL(BEGIN TRANSACTION;) + +CREATE_TABLE(CertificateInfo) + COLUMN_NOT_NULL(certificate, TEXT,DEFAULT '') + COLUMN_NOT_NULL(result, INT, DEFAULT 0) + TABLE_CONSTRAINTS(PRIMARY KEY(certificate)) +CREATE_TABLE_END() + +SQL(COMMIT;) diff --git a/modules/certificate_dao/orm/certificate_db_definitions b/modules/certificate_dao/orm/certificate_db_definitions new file mode 100644 index 0000000..6cfdc11 --- /dev/null +++ b/modules/certificate_dao/orm/certificate_db_definitions @@ -0,0 +1,5 @@ +DATABASE_START(certificate) + +#include "certificate_db" + +DATABASE_END() diff --git a/modules/certificate_dao/orm/certificate_db_sql_generator.h b/modules/certificate_dao/orm/certificate_db_sql_generator.h new file mode 100755 index 0000000..07c1816 --- /dev/null +++ b/modules/certificate_dao/orm/certificate_db_sql_generator.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file certificate_db_sql_generator.h + * @author Leerang Song (leerang.song@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL + * input file from database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. +#include + +#include "certificate_db_definitions" diff --git a/modules/certificate_dao/orm/orm_generator_certificate.h b/modules/certificate_dao/orm/orm_generator_certificate.h new file mode 100755 index 0000000..6822708 --- /dev/null +++ b/modules/certificate_dao/orm/orm_generator_certificate.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ORM_GENERATOR_CERTIFICATE_H_ +#define _ORM_GENERATOR_CERTIFICATE_H_ + +#define ORM_GENERATOR_DATABASE_NAME certificate_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif // _ORM_GENERATOR_CERTIFICATE_H_ \ No newline at end of file diff --git a/modules/core/DESCRIPTION b/modules/core/DESCRIPTION new file mode 100644 index 0000000..1369c40 --- /dev/null +++ b/modules/core/DESCRIPTION @@ -0,0 +1 @@ +Main library code diff --git a/modules/core/config.cmake b/modules/core/config.cmake new file mode 100644 index 0000000..13f83d1 --- /dev/null +++ b/modules/core/config.cmake @@ -0,0 +1,153 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# Set DPL core sources +SET(DPL_CORE_SOURCES + ${PROJECT_SOURCE_DIR}/modules/core/src/abstract_waitable_input_adapter.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/abstract_waitable_input_output_adapter.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/abstract_waitable_output_adapter.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/address.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/apply.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/assert.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/atomic.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/binary_queue.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/char_traits.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/colors.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/copy.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/errno_string.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/exception.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/file_input.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/file_output.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/lexical_cast.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/mutable_task_list.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/mutex.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/named_base_pipe.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/named_output_pipe.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/noncopyable.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/once.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/read_write_mutex.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/recursive_mutex.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/scoped_dir.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/serialization.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/single_instance.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/singleton.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/semaphore.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/string.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/task.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/thread.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/type_list.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/union_cast.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/zip_input.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/application.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/main.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/waitable_event.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/waitable_handle.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/waitable_handle_watch_support.cpp + ${PROJECT_SOURCE_DIR}/modules/core/src/generic_event.cpp + PARENT_SCOPE +) + + +# Set DPL core headers +SET(DPL_CORE_HEADERS + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/abstract_input.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/abstract_input_output.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/abstract_output.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/abstract_waitable_input_adapter.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/abstract_waitable_input.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/abstract_waitable_input_output_adapter.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/abstract_waitable_input_output.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/abstract_waitable_output_adapter.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/abstract_waitable_output.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/address.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/aligned.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/apply.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/assert.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/atomic.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/availability.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/binary_queue.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/bind.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/bool_operator.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/char_traits.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/colors.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/copy.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/enable_shared_from_this.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/errno_string.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/exception.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/file_input.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/file_output.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/foreach.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/generic_event.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/lexical_cast.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/mutable_task_list.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/mutex.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/named_base_pipe.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/named_input_pipe.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/named_output_pipe.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/noncopyable.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/once.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/optional.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/optional_typedefs.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/platform.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/preprocessor.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/read_write_mutex.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/recursive_mutex.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scope_guard.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_resource.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_array.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_close.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_dir.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_fclose.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_free.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_ptr.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/scoped_gpointer.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/serialization.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/semaphore.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/shared_ptr.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/single_instance.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/singleton.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/singleton_impl.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/singleton_safe_impl.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/static_block.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/string.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/sstream.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/task.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/thread.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/type_list.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/union_cast.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/workaround.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/zip_input.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/application.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/framework_appcore.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/framework_efl.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/framework_vconf.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/main.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/waitable_event.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/waitable_handle.h + ${PROJECT_SOURCE_DIR}/modules/core/include/dpl/waitable_handle_watch_support.h + PARENT_SCOPE +) + +SET(DPL_CORE_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/core/include + PARENT_SCOPE +) + diff --git a/modules/core/include/DESCRIPTION b/modules/core/include/DESCRIPTION new file mode 100644 index 0000000..6dfd446 --- /dev/null +++ b/modules/core/include/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +Header files, including template implementations diff --git a/modules/core/include/dpl/abstract_input.h b/modules/core/include/dpl/abstract_input.h new file mode 100644 index 0000000..8c0e16a --- /dev/null +++ b/modules/core/include/dpl/abstract_input.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_input.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract input + */ +#ifndef DPL_ABSTRACT_INPUT_H +#define DPL_ABSTRACT_INPUT_H + +#include +#include + +namespace DPL { +class BinaryQueue; +typedef std::auto_ptr BinaryQueueAutoPtr; + +class AbstractInput +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, ReadFailed) + }; + + public: + virtual ~AbstractInput() {} + + /** + * Read binary data from input + * If no data is available method returns NULL buffer. + * In case connection was successfuly close, method returns empty buffer + * + * @param[in] size Maximum number of bytes to read from input + * @return Buffer containing read bytes + * @throw ReadFailed + */ + virtual BinaryQueueAutoPtr Read(size_t size) = 0; +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_INPUT_H diff --git a/modules/core/include/dpl/abstract_input_output.h b/modules/core/include/dpl/abstract_input_output.h new file mode 100644 index 0000000..153d5c4 --- /dev/null +++ b/modules/core/include/dpl/abstract_input_output.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract output + */ +#ifndef DPL_ABSTRACT_INPUT_OUTPUT_H +#define DPL_ABSTRACT_INPUT_OUTPUT_H + +#include +#include + +namespace DPL { +class AbstractInputOutput : + public AbstractInput, + public AbstractOutput +{ + public: + virtual ~AbstractInputOutput() {} +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_INPUT_OUTPUT_H diff --git a/modules/core/include/dpl/abstract_output.h b/modules/core/include/dpl/abstract_output.h new file mode 100644 index 0000000..56c86fb --- /dev/null +++ b/modules/core/include/dpl/abstract_output.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract output + */ +#ifndef DPL_ABSTRACT_OUTPUT_H +#define DPL_ABSTRACT_OUTPUT_H + +#include +#include + +namespace DPL { +class BinaryQueue; +typedef std::auto_ptr BinaryQueueAutoPtr; + +class AbstractOutput +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, WriteFailed) + }; + + public: + virtual ~AbstractOutput() {} + + /** + * Write binary data to output + * If output is blocked, Write returns zero, if instance is a type of + * WaitableAbstractOutput one can wait for writability then + * + * @param[in] buffer Input buffer with data to be written + * @param[in] bufferSize Maximum number of bytes to write from buffer + * @return Number of bytes success successfuly written or zero if output is + * blocked + * @throw WriteFailed + */ + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize) = 0; +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_OUTPUT_H diff --git a/modules/core/include/dpl/abstract_waitable_input.h b/modules/core/include/dpl/abstract_waitable_input.h new file mode 100644 index 0000000..9d957d6 --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_input.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable input + */ +#ifndef DPL_ABSTRACT_WAITABLE_INPUT_H +#define DPL_ABSTRACT_WAITABLE_INPUT_H + +#include +#include + +namespace DPL { +class AbstractWaitableInput : + public AbstractInput +{ + public: + virtual ~AbstractWaitableInput() {} + + virtual WaitableHandle WaitableReadHandle() const = 0; +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_INPUT_H diff --git a/modules/core/include/dpl/abstract_waitable_input_adapter.h b/modules/core/include/dpl/abstract_waitable_input_adapter.h new file mode 100644 index 0000000..43efaee --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_input_adapter.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable input + */ +#ifndef DPL_ABSTRACT_WAITABLE_INPUT_ADAPTER_H +#define DPL_ABSTRACT_WAITABLE_INPUT_ADAPTER_H + +#include +#include +#include + +namespace DPL { +class AbstractWaitableInputAdapter : + public AbstractWaitableInput +{ + private: + AbstractInput *m_input; + WaitableEvent m_waitableEvent; + + public: + explicit AbstractWaitableInputAdapter(AbstractInput *input); + + virtual BinaryQueueAutoPtr Read(size_t size); + + virtual WaitableHandle WaitableReadHandle() const; +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_INPUT_ADAPTER_H diff --git a/modules/core/include/dpl/abstract_waitable_input_output.h b/modules/core/include/dpl/abstract_waitable_input_output.h new file mode 100644 index 0000000..e858f51 --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_input_output.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable input output + */ +#ifndef DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_H +#define DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_H + +#include +#include + +namespace DPL { +class AbstractWaitableInputOutput : + public AbstractWaitableInput, + public AbstractWaitableOutput +{ + public: + virtual ~AbstractWaitableInputOutput() {} +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_H diff --git a/modules/core/include/dpl/abstract_waitable_input_output_adapter.h b/modules/core/include/dpl/abstract_waitable_input_output_adapter.h new file mode 100644 index 0000000..a0322d0 --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_input_output_adapter.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable input output + */ +#ifndef DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_ADAPTER_H +#define DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_ADAPTER_H + +#include +#include +#include + +namespace DPL { +class AbstractWaitableInputOutputAdapter : + public AbstractWaitableInputAdapter, + public AbstractWaitableOutputAdapter +{ + public: + explicit AbstractWaitableInputOutputAdapter( + AbstractInputOutput *inputOutput); +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_INPUT_OUTPUT_ADAPTER_H diff --git a/modules/core/include/dpl/abstract_waitable_output.h b/modules/core/include/dpl/abstract_waitable_output.h new file mode 100644 index 0000000..abcc3f8 --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_output.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable output + */ +#ifndef DPL_ABSTRACT_WAITABLE_OUTPUT_H +#define DPL_ABSTRACT_WAITABLE_OUTPUT_H + +#include +#include + +namespace DPL { +class AbstractWaitableOutput : + public AbstractOutput +{ + public: + virtual ~AbstractWaitableOutput() {} + + virtual WaitableHandle WaitableWriteHandle() const = 0; +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_OUTPUT_H diff --git a/modules/core/include/dpl/abstract_waitable_output_adapter.h b/modules/core/include/dpl/abstract_waitable_output_adapter.h new file mode 100644 index 0000000..9e40bc4 --- /dev/null +++ b/modules/core/include/dpl/abstract_waitable_output_adapter.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract waitable output + */ +#ifndef DPL_ABSTRACT_WAITABLE_OUTPUT_ADAPTER_H +#define DPL_ABSTRACT_WAITABLE_OUTPUT_ADAPTER_H + +#include +#include +#include + +namespace DPL { +class AbstractWaitableOutputAdapter : + public AbstractWaitableOutput +{ + private: + AbstractOutput *m_output; + WaitableEvent m_waitableEvent; + + public: + explicit AbstractWaitableOutputAdapter(AbstractOutput *output); + + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); + + virtual WaitableHandle WaitableWriteHandle() const; +}; +} // namespace DPL + +#endif // DPL_ABSTRACT_WAITABLE_OUTPUT_ADAPTER_H diff --git a/modules/core/include/dpl/address.h b/modules/core/include/dpl/address.h new file mode 100644 index 0000000..05893f9 --- /dev/null +++ b/modules/core/include/dpl/address.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file address.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of address + */ +#ifndef DPL_ADDRESS_H +#define DPL_ADDRESS_H + +#include +#include + +namespace DPL { +class Address +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InvalidAddress) + }; + + private: + std::string m_address; + unsigned short m_port; + + public: + Address(); + Address(const std::string &address); + Address(const std::string &address, unsigned short port); + + virtual ~Address(); + + std::string GetAddress() const; + unsigned short GetPort() const; + + std::string ToString() const; + + bool operator<(const Address &addr) const; +}; +} // namespace DPL + +#endif // DPL_ADDRESS_H diff --git a/modules/core/include/dpl/aligned.h b/modules/core/include/dpl/aligned.h new file mode 100644 index 0000000..4400545 --- /dev/null +++ b/modules/core/include/dpl/aligned.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file aligned.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of aligned attribute from + * gcc + */ +#ifndef DPL_ALIGNED_H +#define DPL_ALIGNED_H + +#define DPL_ALIGNED(n) __attribute__((aligned(n))) + +#endif // DPL_ALIGNED_H diff --git a/modules/core/include/dpl/application.h b/modules/core/include/dpl/application.h new file mode 100644 index 0000000..d4d9754 --- /dev/null +++ b/modules/core/include/dpl/application.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file application.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC application support + */ +#ifndef DPL_APPLICATION_H +#define DPL_APPLICATION_H + +#include +#include +#include +#include +#include + +namespace DPL { +class Application +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, TooManyInstances) + DECLARE_EXCEPTION_TYPE(Base, FrameworkError) + }; + + private: + static int app_create(void *data); + static int app_terminate(void *data); + static int app_pause(void *data); + static int app_resume(void *data); + static int app_reset(bundle *b, void *data); + + protected: + int m_argc; + char **m_argv; + std::string m_applicationName; + + bool m_mainWindowVisible; + + virtual void OnCreate(); + virtual void OnStart(); + virtual void OnStop(); + virtual void OnResume(); + virtual void OnPause(); + virtual void OnRelaunch(); + virtual void OnReset(bundle *b); + virtual void OnTerminate(); + virtual void OnLowMemory(); + virtual void OnLowBattery(); + virtual void OnLanguageChanged(); + + public: + Application(int argc, + char **argv, + const std::string &applicationName, + bool showMainWindow = true); + virtual ~Application(); + + /** + * @brief Execute application and start message processing + */ + virtual int Exec(); + + /* + * @brief Sends quit message to application message loop + */ + virtual void Quit(); +}; + +class ApplicationExt : public Application +{ + public: + ApplicationExt(int argc, + char **argv, + const std::string &applicationName, + bool showMainWindow = true); + virtual ~ApplicationExt(); + + /** + * @brief Execute application and start message processing + */ + virtual int Exec(); + + /* + * @brief Sends quit message to application message loop + */ + virtual void Quit(); + + private: + static DPL::Atomic m_useCount; +}; +} // namespace DPL + +#endif // DPL_APPLICATION_H diff --git a/modules/core/include/dpl/apply.h b/modules/core/include/dpl/apply.h new file mode 100644 index 0000000..fc1be53 --- /dev/null +++ b/modules/core/include/dpl/apply.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file apply.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Implementation file for Apply functionality. + */ +#ifndef DPL_APPLY_H_ +#define DPL_APPLY_H_ + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ // C++11 compatibility check +# include +#else + +#include +#include + +namespace DPL { +enum class ExtraArgsInsertPolicy +{ + /** + * Extra arguments will be add at the end of the argument list + * passed to operation call. + */ + Append, + + /** + * Extra arguments will be add at the begining of the argument list + * passed to operation call. + */ + Prepend +}; + +template +struct _ApplyDispatchByPolicy; + +template +Result Apply(Operation op, + const std::tuple& t, + ArgsE && ... extra) +{ + return _ApplyDispatchByPolicy:: + template Apply(op, t, std::forward(extra) ...); +} + +template +struct _ApplyTuple +{ + template + static Result Apply(Operation op, + const std::tuple& t1, + const std::tuple& t2, + Args && ... args) + { + return _ApplyTuple:: + template Apply(op, + t1, + t2, + std::get(t1), + std::forward(args) ...); + } +}; + +template +struct _ApplyTuple<0, M> +{ + template + static Result Apply(Operation op, + const std::tuple& t1, + const std::tuple& t2, + Args && ... args) + { + return _ApplyTuple<0, M - 1>:: + template Apply(op, + t1, + t2, + std::get(t2), + std::forward(args) ...); + } +}; + +template<> +struct _ApplyTuple<0, 0> +{ + template + static Result Apply(Operation op, + const std::tuple&, + const std::tuple&, + Args && ... args) + { + return op(std::forward(args) ...); + } +}; + +template +struct _ApplyArgs +{ + template + static Result Apply(Operation op, + const std::tuple& t, + Args && ... args) + { + return _ApplyArgs:: + template Apply(op, + t, + std::get(t), + std::forward(args) ...); + } +}; + +template<> +struct _ApplyArgs<0> +{ + template + static Result Apply(Operation op, + const std::tuple&, + Args && ... args) + { + return op(std::forward(args) ...); + } +}; + +template<> +struct _ApplyDispatchByPolicy +{ + template + static Result Apply(Operation op, + const std::tuple& t, + ArgsE && ... extra) + { + return _ApplyArgs:: + template Apply(op, + t, + std::forward(extra) ...); + } +}; + +template<> +struct _ApplyDispatchByPolicy +{ + template + static Result Apply(Operation op, + const std::tuple& t, + ArgsE && ... extra) + { + return _ApplyTuple:: + template Apply(op, + t, + std::make_tuple(std::forward( + extra) ...)); + } +}; +} // namespace DPL + +#endif // __GXX_EXPERIMENTAL_CXX0X__ + +#endif // DPL_APPLY_H_ diff --git a/modules/core/include/dpl/assert.h b/modules/core/include/dpl/assert.h new file mode 100644 index 0000000..abdb481 --- /dev/null +++ b/modules/core/include/dpl/assert.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file assert.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of assert + */ +#ifndef DPL_ASSERT_H +#define DPL_ASSERT_H + +namespace DPL { +// Assertion handler procedure +// Do not call directly +// Always use Assert macro +void AssertProc(const char *condition, + const char *file, + int line, + const char *function) __attribute__ ((__noreturn__)); +} // namespace DPL + +#define Assert(Condition) do { if (!(Condition)) { DPL::AssertProc(#Condition, \ + __FILE__, \ + __LINE__, \ + __FUNCTION__); \ + } } while (0) + +#define AssertMsg(Condition, Msg) \ + do { \ + if (!(Condition)) { \ + DPL::AssertProc( \ + (std::string(std::string(#Condition)+" ") + Msg).c_str(), \ + __FILE__, __LINE__, __FUNCTION__); \ + } \ + } while (0) + +#endif // DPL_ASSERT_H diff --git a/modules/core/include/dpl/atomic.h b/modules/core/include/dpl/atomic.h new file mode 100644 index 0000000..50c4a1a --- /dev/null +++ b/modules/core/include/dpl/atomic.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file atomic.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of atomic + */ +#ifndef DPL_ATOMIC_H +#define DPL_ATOMIC_H + +#pragma GCC system_header +#include + +namespace DPL { +class Atomic +{ + public: + typedef gint ValueType; + + private: + volatile ValueType m_value; + + public: + Atomic(ValueType value = static_cast(0)); + + ValueType ExchangeAndAdd(ValueType value); + bool CompareAndExchange(ValueType oldValue, ValueType newValue); + bool operator--(); + void operator++(); + + operator ValueType() const; +}; +} // namespace DPL + +#endif // DPL_ATOMIC_H diff --git a/modules/core/include/dpl/availability.h b/modules/core/include/dpl/availability.h new file mode 100644 index 0000000..0813892 --- /dev/null +++ b/modules/core/include/dpl/availability.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file availability.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ +#ifndef DPL_AVAILABILITY_H +#define DPL_AVAILABILITY_H + +#define DPL_DEPRECATED __attribute__((deprecated)) +#define DPL_DEPRECATED_WITH_MESSAGE(msg) __attribute__((deprecated(msg))) + +#define DPL_UNUSED __attribute__((unused)) +#define DPL_UNUSED_PARAM(variable) (void)variable + +#endif // DPL_AVAILABILITY_H diff --git a/modules/core/include/dpl/binary_queue.h b/modules/core/include/dpl/binary_queue.h new file mode 100644 index 0000000..f4fa278 --- /dev/null +++ b/modules/core/include/dpl/binary_queue.h @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file binary_queue.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of binary queue + */ +#ifndef DPL_BINARY_QUEUE_H +#define DPL_BINARY_QUEUE_H + +#include +#include +#include +#include +#include + +namespace DPL { +/** + * Binary stream implemented as constant size bucket list + * + * @todo Add optimized implementation for FlattenConsume + */ +class BinaryQueue : + public AbstractInputOutput +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OutOfData) + }; + + typedef void (*BufferDeleter)(const void *buffer, size_t bufferSize, + void *userParam); + static void BufferDeleterFree(const void *buffer, + size_t bufferSize, + void *userParam); + + class BucketVisitor + { + public: + /** + * Destructor + */ + virtual ~BucketVisitor(); + + /** + * Visit bucket + * + * @return none + * @param[in] buffer Constant pointer to bucket data buffer + * @param[in] bufferSize Number of bytes in bucket + */ + virtual void OnVisitBucket(const void *buffer, size_t bufferSize) = 0; + }; + + private: + struct Bucket : + private Noncopyable + { + const void *buffer; + const void *ptr; + size_t size; + size_t left; + + BufferDeleter deleter; + void *param; + + Bucket(const void *buffer, + size_t bufferSize, + BufferDeleter deleter, + void *userParam); + virtual ~Bucket(); + }; + + typedef std::list BucketList; + BucketList m_buckets; + size_t m_size; + + static void DeleteBucket(Bucket *bucket); + + class BucketVisitorCall + { + private: + BucketVisitor *m_visitor; + + public: + BucketVisitorCall(BucketVisitor *visitor); + virtual ~BucketVisitorCall(); + + void operator()(Bucket *bucket) const; + }; + + public: + /** + * Construct empty binary queue + */ + BinaryQueue(); + + /** + * Construct binary queue via bare copy of other binary queue + * + * @param[in] other Other binary queue to copy from + * @warning One cannot assume that bucket structure is preserved during copy + */ + BinaryQueue(const BinaryQueue &other); + + /** + * Destructor + */ + virtual ~BinaryQueue(); + + /** + * Construct binary queue via bare copy of other binary queue + * + * @param[in] other Other binary queue to copy from + * @warning One cannot assume that bucket structure is preserved during copy + */ + const BinaryQueue &operator=(const BinaryQueue &other); + + /** + * Append copy of @a bufferSize bytes from memory pointed by @a buffer + * to the end of binary queue. Uses default deleter based on free. + * + * @return none + * @param[in] buffer Pointer to buffer to copy data from + * @param[in] bufferSize Number of bytes to copy + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @see BinaryQueue::BufferDeleterFree + */ + void AppendCopy(const void *buffer, size_t bufferSize); + + /** + * Append @a bufferSize bytes from memory pointed by @a buffer + * to the end of binary queue. Uses custom provided deleter. + * Responsibility for deleting provided buffer is transfered to BinaryQueue. + * + * @return none + * @param[in] buffer Pointer to data buffer + * @param[in] bufferSize Number of bytes available in buffer + * @param[in] deleter Pointer to deleter procedure used to free provided + * buffer + * @param[in] userParam User parameter passed to deleter routine + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendUnmanaged( + const void *buffer, + size_t bufferSize, + BufferDeleter deleter = + &BinaryQueue::BufferDeleterFree, + void *userParam = NULL); + + /** + * Append copy of other binary queue to the end of this binary queue + * + * @return none + * @param[in] other Constant reference to other binary queue to copy data + * from + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @warning One cannot assume that bucket structure is preserved during copy + */ + void AppendCopyFrom(const BinaryQueue &other); + + /** + * Move bytes from other binary queue to the end of this binary queue. + * This also removes all bytes from other binary queue. + * This method is designed to be as fast as possible (only pointer swaps) + * and is suggested over making copies of binary queues. + * Bucket structure is preserved after operation. + * + * @return none + * @param[in] other Reference to other binary queue to move data from + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendMoveFrom(BinaryQueue &other); + + /** + * Append copy of binary queue to the end of other binary queue + * + * @return none + * @param[in] other Constant reference to other binary queue to copy data to + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @warning One cannot assume that bucket structure is preserved during copy + */ + void AppendCopyTo(BinaryQueue &other) const; + + /** + * Move bytes from binary queue to the end of other binary queue. + * This also removes all bytes from binary queue. + * This method is designed to be as fast as possible (only pointer swaps) + * and is suggested over making copies of binary queues. + * Bucket structure is preserved after operation. + * + * @return none + * @param[in] other Reference to other binary queue to move data to + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendMoveTo(BinaryQueue &other); + + /** + * Retrieve total size of all data contained in binary queue + * + * @return Number of bytes in binary queue + */ + size_t Size() const; + + /** + * Remove all data from binary queue + * + * @return none + */ + void Clear(); + + /** + * Check if binary queue is empty + * + * @return true if binary queue is empty, false otherwise + */ + bool Empty() const; + + /** + * Remove @a size bytes from beginning of binary queue + * + * @return none + * @param[in] size Number of bytes to remove + * @exception BinaryQueue::Exception::OutOfData Number of bytes is larger + * than available bytes in binary queue + */ + void Consume(size_t size); + + /** + * Retrieve @a bufferSize bytes from beginning of binary queue and copy them + * to user supplied buffer + * + * @return none + * @param[in] buffer Pointer to user buffer to receive bytes + * @param[in] bufferSize Size of user buffer pointed by @a buffer + * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten + * is larger than available bytes in binary queue + */ + void Flatten(void *buffer, size_t bufferSize) const; + + /** + * Retrieve @a bufferSize bytes from beginning of binary queue, copy them + * to user supplied buffer, and remove from binary queue + * + * @return none + * @param[in] buffer Pointer to user buffer to receive bytes + * @param[in] bufferSize Size of user buffer pointed by @a buffer + * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten + * is larger than available bytes in binary queue + */ + void FlattenConsume(void *buffer, size_t bufferSize); + + /** + * Visit each buffer with data using visitor object + * + * @return none + * @param[in] visitor Pointer to bucket visitor + * @see BinaryQueue::BucketVisitor + */ + void VisitBuckets(BucketVisitor *visitor) const; + + /** + * IAbstractInput interface + */ + virtual BinaryQueueAutoPtr Read(size_t size); + + /** + * IAbstractOutput interface + */ + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); +}; + +/** + * Binary queue auto pointer + */ +typedef std::auto_ptr BinaryQueueAutoPtr; +} // namespace DPL + +#endif // DPL_BINARY_QUEUE_H diff --git a/modules/core/include/dpl/bind.h b/modules/core/include/dpl/bind.h new file mode 100644 index 0000000..190319b --- /dev/null +++ b/modules/core/include/dpl/bind.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file bind.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the header file of bind + */ + +/* + * Remarks: + * - Current implementation supports binding member functions (methods) only. + * - Currently up to 8 std::placeholders are supported. + * - Bound delegates are of type std::function<...>. This implies that + * passing arguments at bind-time is not supported (arguments MAY ONLY be + * passed at call-time). + * + * Usage: + * - For usage see tests/core/test_bind.cpp. In general, usage comes down to: + * std::function delegate = + * DPL::Bind(&ObjectType::MethodName, &object); + */ + +#ifndef DPL_BIND_H_ +#define DPL_BIND_H_ + +#include + +#include +#include +#include + +namespace DPL { +namespace detail { +template +struct PlaceholdersBindHelper; + +#define DPL_PLACEHOLDERS_LIST_(z, n, t) ,BOOST_PP_CAT(std::placeholders::_, \ + BOOST_PP_ADD(n, 1)) +#define DPL_PLACEHOLDERS_(count) BOOST_PP_REPEAT(count, \ + DPL_PLACEHOLDERS_LIST_, \ + count) +#define DPL_PLACEHOLDERS_BIND_HELPER_(count) \ +template<> \ +struct PlaceholdersBindHelper \ +{ \ + template \ + static std::function \ + bind(Result(Type::*method)(Args...), Type* object) { \ + return std::bind(method, object DPL_PLACEHOLDERS_(count)); \ + } \ +} + +DPL_PLACEHOLDERS_BIND_HELPER_(0); +DPL_PLACEHOLDERS_BIND_HELPER_(1); +DPL_PLACEHOLDERS_BIND_HELPER_(2); +DPL_PLACEHOLDERS_BIND_HELPER_(3); +DPL_PLACEHOLDERS_BIND_HELPER_(4); +DPL_PLACEHOLDERS_BIND_HELPER_(5); +DPL_PLACEHOLDERS_BIND_HELPER_(6); +DPL_PLACEHOLDERS_BIND_HELPER_(7); +DPL_PLACEHOLDERS_BIND_HELPER_(8); +} + +template +std::function Bind(Result(Type::*method)(Args...), + Type* object) +{ + return detail::PlaceholdersBindHelper::bind(method, + object); +} +} + +#endif // DPL_BIND_H_ diff --git a/modules/core/include/dpl/bool_operator.h b/modules/core/include/dpl/bool_operator.h new file mode 100644 index 0000000..a432df3 --- /dev/null +++ b/modules/core/include/dpl/bool_operator.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file bool_operator.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of bool operator + * + * This module is deprecated, please use standard C++11 feature: explicit conversion operator + * + * example: + * explicit operator bool() {}; + */ +#ifndef DPL_BOOL_OPERATOR_H +#define DPL_BOOL_OPERATOR_H + +#include + +#define DPL_IMPLEMENT_BOOL_OPERATOR(Type, ThisType, CheckPtr, ClassPtr) \ + typedef Type *ThisType::*UnknownBoolType; \ + \ + operator UnknownBoolType() const \ + { \ + return (CheckPtr == NULL) ? NULL : &ThisType::ClassPtr; \ + } DPL_DEPRECATED_WITH_MESSAGE("use standard C++11 feature: explicit conversion operator"); \ + \ + bool operator !() const \ + { \ + return CheckPtr == NULL; \ + } DPL_DEPRECATED_WITH_MESSAGE("use standard C++11 feature: explicit conversion operator"); \ + +#endif // DPL_BOOL_OPERATOR_H diff --git a/modules/core/include/dpl/char_traits.h b/modules/core/include/dpl/char_traits.h new file mode 100644 index 0000000..eb2988f --- /dev/null +++ b/modules/core/include/dpl/char_traits.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file char_traits.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief Char traits are used to create basic_string extended with + * additional features + * Current char traits could be extended in feature to boost + * performance + */ +#ifndef DPL_CHAR_TRAITS +#define DPL_CHAR_TRAITS + +#include +#include +#include +#include +#include + +namespace DPL { +typedef std::char_traits CharTraits; +} // namespace DPL + +#endif // DPL_CHAR_TRAITS diff --git a/modules/core/include/dpl/colors.h b/modules/core/include/dpl/colors.h new file mode 100644 index 0000000..c7cfd53 --- /dev/null +++ b/modules/core/include/dpl/colors.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file colors.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Some constants with definition of colors for Console + * and html output + */ + +#ifndef DPL_COLORS_H +#define DPL_COLORS_H + +namespace DPL { +namespace Colors { +namespace Text { +extern const char* BOLD_GREEN_BEGIN; +extern const char* BOLD_GREEN_END; +extern const char* PURPLE_BEGIN; +extern const char* PURPLE_END; +extern const char* RED_BEGIN; +extern const char* RED_END; +extern const char* GREEN_BEGIN; +extern const char* GREEN_END; +extern const char* CYAN_BEGIN; +extern const char* CYAN_END; +extern const char* BOLD_RED_BEGIN; +extern const char* BOLD_RED_END; +extern const char* BOLD_YELLOW_BEGIN; +extern const char* BOLD_YELLOW_END; +extern const char* BOLD_GOLD_BEGIN; +extern const char* BOLD_GOLD_END; +extern const char* BOLD_WHITE_BEGIN; +extern const char* BOLD_WHITE_END; +} //namespace Text + +namespace Html { +extern const char* BOLD_GREEN_BEGIN; +extern const char* BOLD_GREEN_END; +extern const char* PURPLE_BEGIN; +extern const char* PURPLE_END; +extern const char* RED_BEGIN; +extern const char* RED_END; +extern const char* GREEN_BEGIN; +extern const char* GREEN_END; +extern const char* CYAN_BEGIN; +extern const char* CYAN_END; +extern const char* BOLD_RED_BEGIN; +extern const char* BOLD_RED_END; +extern const char* BOLD_YELLOW_BEGIN; +extern const char* BOLD_YELLOW_END; +extern const char* BOLD_GOLD_BEGIN; +extern const char* BOLD_GOLD_END; +extern const char* BOLD_WHITE_BEGIN; +extern const char* BOLD_WHITE_END; +} //namespace Html +} //namespace Colors +} //namespace DPL + +#endif /* DPL_COLORS_H */ diff --git a/modules/core/include/dpl/copy.h b/modules/core/include/dpl/copy.h new file mode 100644 index 0000000..e796a61 --- /dev/null +++ b/modules/core/include/dpl/copy.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file copy.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of copy + */ +#ifndef DPL_COPY_H +#define DPL_COPY_H + +#include +#include +#include + +namespace DPL { +/** + * Copy failed exception + */ +DECLARE_EXCEPTION_TYPE(Exception, CopyFailed) + +/** + * Copy all bytes abstract waitable input to abstract waitable output + * + * @param[in] input Abstract waitable input to copy from + * @param[in] output Abstract waitable output to copy to + * @throw CopyFailed An error occurred while copying. Look into exception trace + * for details. + */ +void Copy(AbstractWaitableInput *input, AbstractWaitableOutput *output); + +/** + * Copy exactly totalBytes bytes abstract waitable input to abstract waitable + * output + * + * @param[in] input Abstract waitable input to copy from + * @param[in] output Abstract waitable output to copy to + * @throw CopyFailed An error occurred while copying. Look into exception trace + * for details. + */ +void Copy(AbstractWaitableInput *input, + AbstractWaitableOutput *output, + size_t totalBytes); +} // namespace DPL + +#endif // DPL_COPY_H diff --git a/modules/core/include/dpl/enable_shared_from_this.h b/modules/core/include/dpl/enable_shared_from_this.h new file mode 100644 index 0000000..0a0fb3a --- /dev/null +++ b/modules/core/include/dpl/enable_shared_from_this.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file enable_shared_from_this.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of shared pointer RAII + */ +#ifndef DPL_ENABLE_SHARED_FROM_THIS_H +#define DPL_ENABLE_SHARED_FROM_THIS_H + +#include +#include +#include + +namespace DPL { +template +class EnableSharedFromThis : private Noncopyable +{ + private: + // A weak pointer to shared counter + SharedCounter *m_counter; + Class *m_ptr; + + public: + DPL::SharedPtr SharedFromThis() + { + Assert(m_counter != NULL && "Pointer is not shared!"); + return SharedPtr(m_counter, m_ptr); + } + + DPL::SharedPtr SharedFromThis() const + { + Assert(m_counter != NULL && "Pointer is not shared!"); + return SharedPtr(m_counter, m_ptr); + } + + // For internal SharedPtr usage only. Do not call directly. + void _Internal_AcceptSharedPtr(SharedCounter *counter, Class *ptr) + { + m_counter = counter; + m_ptr = ptr; + } + + EnableSharedFromThis() : + m_counter(NULL), + m_ptr(NULL) + {} + + virtual ~EnableSharedFromThis() + {} +}; +} // namespace DPL + +#endif // DPL_ENABLE_SHARED_FROM_THIS_H diff --git a/modules/core/include/dpl/errno_string.h b/modules/core/include/dpl/errno_string.h new file mode 100644 index 0000000..446dbc9 --- /dev/null +++ b/modules/core/include/dpl/errno_string.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file errno_string.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of errno string + */ +#ifndef DPL_ERRNO_STRING_H +#define DPL_ERRNO_STRING_H + +#include +#include +#include + +namespace DPL { +DECLARE_EXCEPTION_TYPE(DPL::Exception, InvalidErrnoValue) + +std::string GetErrnoString(int error = errno); +} // namespace DPL + +#endif // DPL_ERRNO_STRING_H diff --git a/modules/core/include/dpl/exception.h b/modules/core/include/dpl/exception.h new file mode 100644 index 0000000..cdbdc53 --- /dev/null +++ b/modules/core/include/dpl/exception.h @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file exception.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for base exception + */ +#ifndef DPL_EXCEPTION_H +#define DPL_EXCEPTION_H + +#include +#include +#include +#include +#include +#include + +namespace DPL { +void LogUnhandledException(const std::string &str); +void LogUnhandledException(const std::string &str, + const char *filename, + int line, + const char *function); +} + +namespace DPL { +class Exception +{ + private: + static unsigned int m_exceptionCount; + static Exception* m_lastException; + static void (*m_terminateHandler)(); + + static void AddRef(Exception* exception) + { + if (!m_exceptionCount) { + m_terminateHandler = std::set_terminate(&TerminateHandler); + } + + ++m_exceptionCount; + m_lastException = exception; + } + + static void UnRef(Exception* e) + { + if (m_lastException == e) { + m_lastException = NULL; + } + + --m_exceptionCount; + + if (!m_exceptionCount) { + std::set_terminate(m_terminateHandler); + m_terminateHandler = NULL; + } + } + + static void TerminateHandler() + { + if (m_lastException != NULL) { + DisplayKnownException(*m_lastException); + abort(); + } else { + DisplayUnknownException(); + abort(); + } + } + + Exception *m_reason; + std::string m_path; + std::string m_function; + int m_line; + + protected: + std::string m_message; + std::string m_className; + + public: + static std::string KnownExceptionToString(const Exception &e) + { + std::ostringstream message; + message << + "\033[1;5;31m\n=== Unhandled DPL exception occurred ===\033[m\n\n"; + message << "\033[1;33mException trace:\033[m\n\n"; + message << e.DumpToString(); + message << "\033[1;31m\n=== Will now abort ===\033[m\n"; + + return message.str(); + } + + static std::string UnknownExceptionToString() + { + std::ostringstream message; + message << + "\033[1;5;31m\n=== Unhandled non-DPL exception occurred ===\033[m\n\n"; + message << "\033[1;31m\n=== Will now abort ===\033[m\n"; + + return message.str(); + } + + static void DisplayKnownException(const Exception& e) + { + LogUnhandledException(KnownExceptionToString(e).c_str()); + } + + static void DisplayUnknownException() + { + LogUnhandledException(UnknownExceptionToString().c_str()); + } + + Exception(const Exception &other) + { + // Deep copy + if (other.m_reason != NULL) { + m_reason = new Exception(*other.m_reason); + } else { + m_reason = NULL; + } + + m_message = other.m_message; + m_path = other.m_path; + m_function = other.m_function; + m_line = other.m_line; + + m_className = other.m_className; + + AddRef(this); + } + + const Exception &operator =(const Exception &other) + { + if (this == &other) { + return *this; + } + + // Deep copy + if (other.m_reason != NULL) { + m_reason = new Exception(*other.m_reason); + } else { + m_reason = NULL; + } + + m_message = other.m_message; + m_path = other.m_path; + m_function = other.m_function; + m_line = other.m_line; + + m_className = other.m_className; + + AddRef(this); + + return *this; + } + + Exception(const char *path, + const char *function, + int line, + const std::string &message) : + m_reason(NULL), + m_path(path), + m_function(function), + m_line(line), + m_message(message) + { + AddRef(this); + } + + Exception(const char *path, + const char *function, + int line, + const Exception &reason, + const std::string &message) : + m_reason(new Exception(reason)), + m_path(path), + m_function(function), + m_line(line), + m_message(message) + { + AddRef(this); + } + + virtual ~Exception() throw() + { + if (m_reason != NULL) { + delete m_reason; + m_reason = NULL; + } + + UnRef(this); + } + + void Dump() const + { + // Show reason first + if (m_reason != NULL) { + m_reason->Dump(); + } + + // Afterward, dump exception + const char *file = strchr(m_path.c_str(), '/'); + + if (file == NULL) { + file = m_path.c_str(); + } else { + ++file; + } + + printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n", + file, m_line, + m_function.c_str(), + m_className.c_str(), + m_message.empty() ? "" : m_message.c_str()); + } + + std::string DumpToString() const + { + std::string ret; + if (m_reason != NULL) { + ret = m_reason->DumpToString(); + } + + const char *file = strchr(m_path.c_str(), '/'); + + if (file == NULL) { + file = m_path.c_str(); + } else { + ++file; + } + + char buf[1024]; + snprintf(buf, + sizeof(buf), + "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n", + file, + m_line, + m_function.c_str(), + m_className.c_str(), + m_message.empty() ? "" : m_message.c_str()); + + buf[sizeof(buf) - 1] = '\n'; + ret += buf; + + return ret; + } + + Exception *GetReason() const + { + return m_reason; + } + + std::string GetPath() const + { + return m_path; + } + + std::string GetFunction() const + { + return m_function; + } + + int GetLine() const + { + return m_line; + } + + std::string GetMessage() const + { + return m_message; + } + + std::string GetClassName() const + { + return m_className; + } +}; +} // namespace DPL + +#define Try try + +#define Throw(ClassName) \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__) + +#define ThrowMsg(ClassName, Message) \ + do \ + { \ + std::ostringstream dplLoggingStream; \ + dplLoggingStream << Message; \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str()); \ + } while (0) + +#define ReThrow(ClassName) \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception) + +#define ReThrowMsg(ClassName, Message) \ + throw ClassName(__FILE__, \ + __FUNCTION__, \ + __LINE__, \ + _rethrown_exception, \ + Message) + +#define Catch(ClassName) \ + catch (const ClassName &_rethrown_exception) + +#define DECLARE_EXCEPTION_TYPE(BaseClass, Class) \ + class Class : \ + public BaseClass \ + { \ + public: \ + Class(const char *path, \ + const char *function, \ + int line, \ + const std::string & message = std::string()) : \ + BaseClass(path, function, line, message) \ + { \ + BaseClass::m_className = #Class; \ + } \ + \ + Class(const char *path, \ + const char *function, \ + int line, \ + const DPL::Exception & reason, \ + const std::string & message = std::string()) : \ + BaseClass(path, function, line, reason, message) \ + { \ + BaseClass::m_className = #Class; \ + } \ + }; + +#define UNHANDLED_EXCEPTION_HANDLER_BEGIN try + +#define UNHANDLED_EXCEPTION_HANDLER_END \ + catch (const DPL::Exception &exception) \ + { \ + std::ostringstream msg; \ + msg << DPL::Exception::KnownExceptionToString(exception); \ + DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + catch (std::exception& e) \ + { \ + std::ostringstream msg; \ + msg << e.what(); \ + msg << "\n"; \ + msg << DPL::Exception::UnknownExceptionToString(); \ + DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + catch (...) \ + { \ + std::ostringstream msg; \ + msg << DPL::Exception::UnknownExceptionToString(); \ + DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } + +namespace DPL { +namespace CommonException { +/** + * Internal exception definitions + * + * These should normally not happen. + * Usually, exception trace with internal error includes + * important messages. + */ +DECLARE_EXCEPTION_TYPE(Exception, InternalError) ///< Unexpected error from + // underlying libraries or + // kernel +} +} + +#endif // DPL_EXCEPTION_H diff --git a/modules/core/include/dpl/file_input.h b/modules/core/include/dpl/file_input.h new file mode 100644 index 0000000..3adcf21 --- /dev/null +++ b/modules/core/include/dpl/file_input.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file file_input.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of file input + */ +#ifndef DPL_FILE_INPUT_H +#define DPL_FILE_INPUT_H + +#include +#include +#include + +namespace DPL { +class FileInput : + private Noncopyable, + public AbstractWaitableInput +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + + protected: + int m_fd; + + public: + FileInput(); + FileInput(const std::string &fileName); + virtual ~FileInput(); + + void Open(const std::string &fileName); + void Close(); + + // AbstractInput + virtual BinaryQueueAutoPtr Read(size_t size); + + // AbstractWaitableInput + virtual WaitableHandle WaitableReadHandle() const; +}; +} // namespace DPL + +#endif // DPL_FILE_INPUT_H diff --git a/modules/core/include/dpl/file_output.h b/modules/core/include/dpl/file_output.h new file mode 100644 index 0000000..90be8cd --- /dev/null +++ b/modules/core/include/dpl/file_output.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file file_output.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of file output + */ +#ifndef DPL_FILE_OUTPUT_H +#define DPL_FILE_OUTPUT_H + +#include +#include +#include + +namespace DPL { +class FileOutput : + private Noncopyable, + public AbstractWaitableOutput +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + + protected: + int m_fd; + + public: + FileOutput(); + FileOutput(const std::string &fileName); + virtual ~FileOutput(); + + void Open(const std::string &fileName); + void Close(); + + // AbstractOutput + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); + + // AbstracWaitableOutput + virtual WaitableHandle WaitableWriteHandle() const; +}; +} // namespace DPL + +#endif // DPL_FILE_OUTPUT_H diff --git a/modules/core/include/dpl/foreach.h b/modules/core/include/dpl/foreach.h new file mode 100644 index 0000000..bbe477a --- /dev/null +++ b/modules/core/include/dpl/foreach.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file foreach.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of foreach macro for stl + * containers + */ +#ifndef DPL_FOREACH_H +#define DPL_FOREACH_H + +#include + +namespace DPL { +namespace Private { +/* + * Used to detect type of valid reference to value object. + */ +template +T& ValueReference(T& t) +{ + return(t); +} + +template +const T& ValueReference(const T& t) +{ + return(t); +} +} //Private +} //DPL + +#define DPL_FOREACH_IMPL(temporaryName, iterator, container) \ + __typeof__ (DPL::Private::ValueReference((container))) & \ + temporaryName = (container); \ + for (__typeof__ (temporaryName.begin())iterator = \ + temporaryName.begin(); \ + (iterator) != temporaryName.end(); ++iterator) + +#define FOREACH(iterator, container) \ + DPL_FOREACH_IMPL( \ + DPL_MACRO_CONCAT(foreachContainerReference, __COUNTER__), \ + iterator, \ + container) + +#endif // DPL_FOREACH_H diff --git a/modules/core/include/dpl/framework_appcore.h b/modules/core/include/dpl/framework_appcore.h new file mode 100644 index 0000000..034134a --- /dev/null +++ b/modules/core/include/dpl/framework_appcore.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file framework_appcore.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the forward header file for APPCORE framework + */ +#pragma GCC system_header +#include diff --git a/modules/core/include/dpl/framework_efl.h b/modules/core/include/dpl/framework_efl.h new file mode 100644 index 0000000..6246587 --- /dev/null +++ b/modules/core/include/dpl/framework_efl.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file framework_efl.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the forward header file for EFL framework + */ +#pragma GCC system_header +#include +#include +#include diff --git a/modules/core/include/dpl/framework_vconf.h b/modules/core/include/dpl/framework_vconf.h new file mode 100644 index 0000000..8de9b31 --- /dev/null +++ b/modules/core/include/dpl/framework_vconf.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file framework_vconf.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the forward header file for VCONF + */ +#pragma GCC system_header +#include +#include diff --git a/modules/core/include/dpl/generic_event.h b/modules/core/include/dpl/generic_event.h new file mode 100644 index 0000000..b20d913 --- /dev/null +++ b/modules/core/include/dpl/generic_event.h @@ -0,0 +1,639 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_event.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC generic event + */ +#ifndef DPL_GENERIC_EVENT_H +#define DPL_GENERIC_EVENT_H + +namespace DPL { +class EventSender +{ + public: + explicit EventSender(void *sender) : + m_sender(sender) + {} + + void* GetSender() const + { + return m_sender; + } + + private: + void *m_sender; +}; + +class GenericEvent +{ + protected: + void *m_sender; + + public: + explicit GenericEvent(const EventSender &sender) : + m_sender(sender.GetSender()) + {} + + virtual ~GenericEvent() + {} + + void *GetSender() const + { + return m_sender; + } +}; + +class GenericEvent0 : + public GenericEvent +{ + public: + explicit GenericEvent0(const EventSender &sender) : + GenericEvent(sender) + {} + + virtual ~GenericEvent0() + {} +}; + +template +class GenericEvent1 : + public GenericEvent0 +{ + public: + typedef Arg0Type Arg0; + + protected: + Arg0 m_arg0; + + public: + explicit GenericEvent1(const EventSender &sender) : + GenericEvent0(sender) + {} + + GenericEvent1(Arg0 arg0, const EventSender &sender) : + GenericEvent0(sender), + m_arg0(arg0) + {} + + virtual ~GenericEvent1() + {} + + Arg0 GetArg0() const + { + return m_arg0; + } +}; + +template +class GenericEvent2 : + public GenericEvent1 +{ + public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + + protected: + Arg1 m_arg1; + + public: + explicit GenericEvent2(const EventSender &sender) : + GenericEvent1(sender) + {} + + GenericEvent2(Arg0 arg0, Arg1 arg1, const EventSender &sender) : + GenericEvent1(arg0, sender), + m_arg1(arg1) + {} + + virtual ~GenericEvent2() + {} + + Arg1 GetArg1() const + { + return m_arg1; + } +}; + +template +class GenericEvent3 : + public GenericEvent2 +{ + public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + + protected: + Arg2 m_arg2; + + public: + explicit GenericEvent3(const EventSender &sender) : + GenericEvent2(sender) + {} + + GenericEvent3(Arg0 arg0, Arg1 arg1, Arg2 arg2, const EventSender &sender) : + GenericEvent2(arg0, arg1, sender), + m_arg2(arg2) + {} + + virtual ~GenericEvent3() + {} + + Arg2 GetArg2() const + { + return m_arg2; + } +}; + +template +class GenericEvent4 : + public GenericEvent3 +{ + public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + typedef Arg3Type Arg3; + + protected: + Arg3 m_arg3; + + public: + explicit GenericEvent4(const EventSender &sender) : + GenericEvent3(sender) + {} + + GenericEvent4(Arg0 arg0, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + const EventSender &sender) : + GenericEvent3(arg0, arg1, arg2, sender), + m_arg3(arg3) + {} + + virtual ~GenericEvent4() + {} + + Arg3 GetArg3() const + { + return m_arg3; + } +}; + +template +class GenericEvent5 : + public GenericEvent4 +{ + public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + typedef Arg3Type Arg3; + typedef Arg4Type Arg4; + + protected: + Arg4 m_arg4; + + public: + explicit GenericEvent5(const EventSender &sender) : + GenericEvent4(sender) + {} + + GenericEvent5(Arg0 arg0, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4, + const EventSender &sender) : + GenericEvent4(arg0, arg1, arg2, + arg3, sender), + m_arg4(arg4) + {} + + virtual ~GenericEvent5() + {} + + Arg4 GetArg4() const + { + return m_arg4; + } +}; + +template +class GenericEvent6 : + public GenericEvent5 +{ + public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + typedef Arg3Type Arg3; + typedef Arg4Type Arg4; + typedef Arg5Type Arg5; + + protected: + Arg5 m_arg5; + + public: + explicit GenericEvent6(const EventSender &sender) : + GenericEvent5(sender) + {} + + GenericEvent6(Arg0 arg0, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4, + Arg5 arg5, + const EventSender &sender) : + GenericEvent5(arg0, + arg1, + arg2, + arg3, + arg4, + sender), + m_arg5(arg5) + {} + + virtual ~GenericEvent6() + {} + + Arg5 GetArg5() const + { + return m_arg5; + } +}; + +template +class GenericEvent7 : + public GenericEvent6 +{ + public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + typedef Arg3Type Arg3; + typedef Arg4Type Arg4; + typedef Arg5Type Arg5; + typedef Arg6Type Arg6; + + protected: + Arg6 m_arg6; + + public: + explicit GenericEvent7(const EventSender &sender) : + GenericEvent6(sender) + {} + + GenericEvent7(Arg0 arg0, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4, + Arg5 arg5, + Arg6 arg6, + const EventSender &sender) : + GenericEvent6(arg0, arg1, arg2, arg3, arg4, arg5, sender), + m_arg6(arg6) + {} + + virtual ~GenericEvent7() + {} + + Arg6 GetArg6() const + { + return m_arg6; + } +}; + +template +class GenericEvent8 : + public GenericEvent7 +{ + public: + typedef Arg0Type Arg0; + typedef Arg1Type Arg1; + typedef Arg2Type Arg2; + typedef Arg3Type Arg3; + typedef Arg4Type Arg4; + typedef Arg5Type Arg5; + typedef Arg6Type Arg6; + typedef Arg7Type Arg7; + + protected: + Arg7 m_arg7; + + public: + explicit GenericEvent8(const EventSender &sender) : + GenericEvent7(sender) + {} + + GenericEvent8(Arg0 arg0, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4, + Arg5 arg5, + Arg6 arg6, + Arg7 arg7, + const EventSender &sender) : + GenericEvent7(arg0, arg1, arg2, arg3, arg4, arg5, + arg6, sender), + m_arg7(arg7) + {} + + virtual ~GenericEvent8() + {} + + Arg7 GetArg7() const + { + return m_arg7; + } +}; +} // namespace DPL + +#define DECLARE_GENERIC_EVENT_0(ClassName) \ + class ClassName : \ + public DPL::GenericEvent0 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender & sender = \ + DPL::EventSender(NULL)) : \ + DPL::GenericEvent0(sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_1(ClassName, Arg0Type) \ + class ClassName : \ + public DPL::GenericEvent1 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender & sender = \ + DPL::EventSender(NULL)) : \ + DPL::GenericEvent1(sender) \ + { \ + } \ + \ + explicit ClassName(Arg0Type arg0, \ + const DPL::EventSender & sender = \ + DPL::EventSender(NULL)) : \ + DPL::GenericEvent1(arg0, sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_2(ClassName, Arg0Type, Arg1Type) \ + class ClassName : \ + public DPL::GenericEvent2 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender & sender = \ + DPL::EventSender(NULL)) : \ + DPL::GenericEvent2(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, Arg1Type arg1, \ + const DPL::EventSender & sender = DPL::EventSender(NULL)) : \ + DPL::GenericEvent2(arg0, arg1, sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_3(ClassName, Arg0Type, Arg1Type, Arg2Type) \ + class ClassName : \ + public DPL::GenericEvent3 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender & sender = \ + DPL::EventSender(NULL)) : \ + DPL::GenericEvent3(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, Arg1Type arg1, Arg2Type arg2, \ + const DPL::EventSender & sender = DPL::EventSender(NULL)) : \ + DPL::GenericEvent3(arg0, \ + arg1, \ + arg2, \ + sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_4(ClassName, \ + Arg0Type, \ + Arg1Type, \ + Arg2Type, \ + Arg3Type) \ + class ClassName : \ + public DPL::GenericEvent4 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender & sender = \ + DPL::EventSender(NULL)) : \ + DPL::GenericEvent4(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, \ + const DPL::EventSender & sender = DPL::EventSender(NULL)) : \ + DPL::GenericEvent4(arg0, \ + arg1, \ + arg2, \ + arg3, \ + sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_5(ClassName, \ + Arg0Type, \ + Arg1Type, \ + Arg2Type, \ + Arg3Type, \ + Arg4Type) \ + class ClassName : \ + public DPL::GenericEvent5 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender & sender = \ + DPL::EventSender(NULL)) : \ + DPL::GenericEvent5( \ + sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, \ + Arg1Type arg1, \ + Arg2Type arg2, \ + Arg3Type arg3, \ + Arg4Type arg4, \ + const DPL::EventSender & sender = DPL::EventSender(NULL)) : \ + DPL::GenericEvent5( \ + arg0, \ + arg1, \ + arg2, \ + arg3, \ + arg4, \ + sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_6(ClassName, \ + Arg0Type, \ + Arg1Type, \ + Arg2Type, \ + Arg3Type, \ + Arg4Type, \ + Arg5Type) \ + class ClassName : \ + public DPL::GenericEvent6 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender & sender = \ + DPL::EventSender(NULL)) : \ + DPL::GenericEvent6(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, \ + Arg1Type arg1, \ + Arg2Type arg2, \ + Arg3Type arg3, \ + Arg4Type arg4, \ + Arg5Type arg5, \ + const DPL::EventSender & sender = DPL::EventSender(NULL)) : \ + DPL::GenericEvent6(arg0, \ + arg1, \ + arg2, \ + arg3, \ + arg4, \ + arg5, \ + sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_7(ClassName, \ + Arg0Type, \ + Arg1Type, \ + Arg2Type, \ + Arg3Type, \ + Arg4Type, \ + Arg5Type, \ + Arg6Type) \ + class ClassName : \ + public DPL::GenericEvent7 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender & sender = \ + DPL::EventSender(NULL)) : \ + DPL::GenericEvent7(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, \ + Arg1Type arg1, \ + Arg2Type arg2, \ + Arg3Type arg3, \ + Arg4Type arg4, \ + Arg5Type arg5, \ + Arg6Type arg6, \ + const DPL::EventSender & sender = DPL::EventSender(NULL)) : \ + DPL::GenericEvent7(arg0, \ + arg1, \ + arg2, \ + arg3, \ + arg4, \ + arg5, \ + arg6, \ + sender) \ + { \ + } \ + }; + +#define DECLARE_GENERIC_EVENT_8(ClassName, \ + Arg0Type, \ + Arg1Type, \ + Arg2Type, \ + Arg3Type, \ + Arg4Type, \ + Arg5Type, \ + Arg6Type, \ + Arg7Type) \ + class ClassName : \ + public DPL::GenericEvent8 \ + { \ + public: \ + explicit ClassName(const DPL::EventSender & sender = \ + DPL::EventSender(NULL)) : \ + DPL::GenericEvent8(sender) \ + { \ + } \ + \ + ClassName(Arg0Type arg0, \ + Arg1Type arg1, \ + Arg2Type arg2, \ + Arg3Type arg3, \ + Arg4Type arg4, \ + Arg5Type arg5, \ + Arg6Type arg6, \ + Arg7Type arg7, \ + const DPL::EventSender & sender = DPL::EventSender(NULL)) : \ + DPL::GenericEvent8(arg0, \ + arg1, \ + arg2, \ + arg3, \ + arg4, \ + arg5, \ + arg6, \ + arg7, \ + sender) \ + { \ + } \ + }; + +#endif // DPL_GENERIC_EVENT_H diff --git a/modules/core/include/dpl/lexical_cast.h b/modules/core/include/dpl/lexical_cast.h new file mode 100644 index 0000000..1b54026 --- /dev/null +++ b/modules/core/include/dpl/lexical_cast.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file lexical_cast.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for lexical cast + */ +#ifndef DPL_LEXICAL_CAST_H +#define DPL_LEXICAL_CAST_H + +#include + +namespace DPL { +template +TargetType lexical_cast(const SourceType &data) +{ + TargetType result; + + std::ostringstream out; + out << data; + + std::istringstream in(out.str()); + in >> result; + + return result; +} +} // namespace DPL + +#endif // DPL_LEXICAL_CAST_H diff --git a/modules/core/include/dpl/main.h b/modules/core/include/dpl/main.h new file mode 100644 index 0000000..cb088cf --- /dev/null +++ b/modules/core/include/dpl/main.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main for EFL + */ +#ifndef DPL_MAIN_H +#define DPL_MAIN_H + +#include +#include +#include +#include +#include +#include + +namespace DPL { +class Main : + public WaitableHandleWatchSupport +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + }; + + protected: + Ecore_Fd_Handler *m_invokerHandler; + + static Eina_Bool StaticDispatchInvoker(void *data, + Ecore_Fd_Handler *fd_handler); + static Eina_Bool StaticDispatchReadWatcher(void *data, + Ecore_Fd_Handler *fd_handler); + static Eina_Bool StaticDispatchWriteWatcher(void *data, + Ecore_Fd_Handler *fd_handler); + + typedef std::list EcoreFdHandlerList; + + EcoreFdHandlerList m_readWatchersList; + EcoreFdHandlerList m_writeWatchersList; + + void DispatchInvoker(); + void DispatchReadWatcher(WaitableHandle waitableHandle); + void DispatchWriteWatcher(WaitableHandle waitableHandle); + + void ReloadWatchList(); + + // WaitableHandleWatchSupport + virtual Thread *GetInvokerThread(); + virtual void HandleDirectInvoker(); + +#ifdef DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND + // GLIB loop intergration workaround + typedef int (*EcoreSelectType)(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout); + EcoreSelectType m_oldEcoreSelect; + + static int EcoreSelectInterceptor(int nfds, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout); +#endif // DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND + + public: + explicit Main(); + virtual ~Main(); +}; + +/** + * Main singleton + */ +typedef Singleton
MainSingleton; +} // namespace DPL + +#endif // DPL_MAIN_H diff --git a/modules/core/include/dpl/mutable_task_list.h b/modules/core/include/dpl/mutable_task_list.h new file mode 100644 index 0000000..9facbd3 --- /dev/null +++ b/modules/core/include/dpl/mutable_task_list.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file mutable_task_list.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + * @brief Header file for task list + */ +#ifndef DPL_MUTABLE_TASK_LIST_H +#define DPL_MUTABLE_TASK_LIST_H + +#include +#include + +namespace DPL { +class MutableTaskList : + public Task +{ + private: + typedef std::list Tasks; + + Tasks m_tasks; + Tasks::iterator m_currentTask; + + bool m_running; + + protected: + void AddTask(Task *task); + + public: + MutableTaskList(); + virtual ~MutableTaskList(); + + bool NextStep(); + bool Abort(); + size_t GetStepCount() const; +}; +} // namespace DPL + +#endif // DPL_MUTABLE_TASK_LIST_H diff --git a/modules/core/include/dpl/mutex.h b/modules/core/include/dpl/mutex.h new file mode 100644 index 0000000..315a92c --- /dev/null +++ b/modules/core/include/dpl/mutex.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file mutex.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of mutex + */ +#ifndef DPL_MUTEX_H +#define DPL_MUTEX_H + +#include +#include +#include + +namespace DPL { +class Mutex : + private Noncopyable +{ + public: + class ScopedLock : + private Noncopyable + { + private: + Mutex *m_mutex; + + public: + explicit ScopedLock(Mutex *mutex); + ~ScopedLock(); + }; + + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, LockFailed) + DECLARE_EXCEPTION_TYPE(Base, UnlockFailed) + }; + + private: + mutable pthread_mutex_t m_mutex; + + void Lock() const; + void Unlock() const; + + public: + Mutex(); + ~Mutex(); +}; +} // namespace DPL + +#endif // DPL_MUTEX_H diff --git a/modules/core/include/dpl/named_base_pipe.h b/modules/core/include/dpl/named_base_pipe.h new file mode 100644 index 0000000..45714ef --- /dev/null +++ b/modules/core/include/dpl/named_base_pipe.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file named_base_pipe.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named base pipe + */ +#ifndef DPL_NAMED_BASE_PIPE_H +#define DPL_NAMED_BASE_PIPE_H + +#include + +namespace DPL { +class NamedBasePipe +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, AlreadyExist) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, DestroyFailed) + }; + + public: + virtual ~NamedBasePipe(); + + static void Create(const std::string &fileName); + static void Destroy(const std::string &fileName); +}; +} // namespace DPL + +#endif // DPL_NAMED_BASE_PIPE_H diff --git a/modules/core/include/dpl/named_input_pipe.h b/modules/core/include/dpl/named_input_pipe.h new file mode 100644 index 0000000..cf7b4b7 --- /dev/null +++ b/modules/core/include/dpl/named_input_pipe.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file named_input_pipe.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named input pipe + */ +#ifndef DPL_NAMED_PIPE_H +#define DPL_NAMED_PIPE_H + +#include +#include +#include + +namespace DPL { +class NamedInputPipe : + public NamedBasePipe, + public FileInput +{}; +} // namespace DPL + +#endif // DPL_NAMED_PIPE_H diff --git a/modules/core/include/dpl/named_output_pipe.h b/modules/core/include/dpl/named_output_pipe.h new file mode 100644 index 0000000..573d1d2 --- /dev/null +++ b/modules/core/include/dpl/named_output_pipe.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file named_output_pipe.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named output pipe + */ +#ifndef DPL_NAMED_OUTPUT_PIPE_H +#define DPL_NAMED_OUTPUT_PIPE_H + +#include +#include +#include +#include + +namespace DPL { +class NamedOutputPipe : + private Noncopyable, + public NamedBasePipe, + public AbstractWaitableOutput +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + + protected: + int m_fifo; + + public: + NamedOutputPipe(); + virtual ~NamedOutputPipe(); + + void Open(const std::string &fileName); + void Close(); + + // AbstractOutput + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); + + // AbstracWaitableOutput + virtual WaitableHandle WaitableWriteHandle() const; +}; +} // namespace DPL + +#endif // DPL_NAMED_OUTPUT_PIPE_H diff --git a/modules/core/include/dpl/noncopyable.h b/modules/core/include/dpl/noncopyable.h new file mode 100644 index 0000000..98d57dd --- /dev/null +++ b/modules/core/include/dpl/noncopyable.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file noncopyable + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of noncopyable + */ +#ifndef DPL_NONCOPYABLE_H +#define DPL_NONCOPYABLE_H + +namespace DPL { +class Noncopyable +{ + private: + Noncopyable(const Noncopyable &); + const Noncopyable &operator=(const Noncopyable &); + + public: + Noncopyable(); + virtual ~Noncopyable(); +}; +} // namespace DPL + +#endif // DPL_NONCOPYABLE_H diff --git a/modules/core/include/dpl/once.h b/modules/core/include/dpl/once.h new file mode 100644 index 0000000..ab3710f --- /dev/null +++ b/modules/core/include/dpl/once.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file once.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of once + */ +#ifndef DPL_ONCE_H +#define DPL_ONCE_H + +#include +#include +#include +#include + +namespace DPL { +class Once : + private Noncopyable +{ + public: + typedef std::function Delegate; + + void Call(Delegate delegate); + + private: + Atomic m_atomic; + Mutex m_mutex; +}; +} // namespace DPL + +#endif // DPL_ONCE_H diff --git a/modules/core/include/dpl/optional.h b/modules/core/include/dpl/optional.h new file mode 100644 index 0000000..d1ec5f3 --- /dev/null +++ b/modules/core/include/dpl/optional.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file optional_value.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + */ + +#ifndef DPL_OPTIONAL_H +#define DPL_OPTIONAL_H + +#include +#include + +namespace DPL { +template +class Optional +{ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, NullReference) + }; + + public: + Optional() : + m_null(true), + m_value() + {} + + Optional(const Type& t) : + m_null(false), + m_value(t) + {} + + bool IsNull() const + { + return m_null; + } + + Type& operator*() + { + if (m_null) { + Throw(typename Exception::NullReference); + } + return m_value; + } + + const Type& operator*() const + { + if (m_null) { + Throw(typename Exception::NullReference); + } + return m_value; + } + + const Type* operator->() const + { + if (m_null) { + Throw(typename Exception::NullReference); + } + return &m_value; + } + + Type* operator->() + { + if (m_null) { + Throw(typename Exception::NullReference); + } + return &m_value; + } + + bool operator!() const + { + return m_null; + } + + Optional& operator=(const Type& other) + { + m_null = false; + m_value = other; + return *this; + } + + bool operator==(const Optional& aSecond) const + { + return LogicalOperator(*this, aSecond, + std::equal_to(), std::equal_to()); + } + + bool operator==(const Type& aSecond) const + { + return Optional(aSecond) == *this; + } + + bool operator!=(const Optional& aSecond) const + { + return !(*this == aSecond); + } + + bool operator<(const Optional& aSecond) const + { + return LogicalOperator(*this, aSecond, + std::less(), std::less()); + } + + bool operator>(const Optional& aSecond) const + { + return LogicalOperator(*this, aSecond, + std::greater(), std::greater()); + } + + bool operator<=(const Optional& aSecond) const + { + return *this == aSecond || *this < aSecond; + } + + bool operator>=(const Optional& aSecond) const + { + return *this == aSecond || *this > aSecond; + } + + static Optional Null; + + private: + bool m_null; + Type m_value; + + template + static bool LogicalOperator(const Optional& aFirst, + const Optional& aSecond, + taComparator aComparator, + taNullComparator aNullComparator) + { + if (aFirst.m_null == aSecond.m_null) { + if (aFirst.m_null) { + return taEquality; + } else { + return aComparator(aFirst.m_value, aSecond.m_value); + } + } else { + return aNullComparator(aFirst.m_null, aSecond.m_null); + } + } +} DPL_DEPRECATED_WITH_MESSAGE("Use boost::optional instead"); + +template +Optional Optional::Null = Optional(); +} //namespace DPL + +template +std::ostream& operator<<(std::ostream& aStream, + const DPL::Optional& aOptional) +{ + if (aOptional.IsNull()) { + return aStream << "null optional"; + } else { + return aStream << *aOptional; + } +} + +#endif // DPL_OPTIONAL_VALUE_H diff --git a/modules/core/include/dpl/optional_typedefs.h b/modules/core/include/dpl/optional_typedefs.h new file mode 100644 index 0000000..8b56b4c --- /dev/null +++ b/modules/core/include/dpl/optional_typedefs.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DPL_OPTIONAL_TYPEDEFS_H +#define DPL_OPTIONAL_TYPEDEFS_H + +#include +#include +#include + +namespace DPL { +typedef Optional OptionalString; +typedef Optional OptionalInt; +typedef Optional OptionalUInt; +typedef Optional OptionalBool; +typedef Optional OptionalFloat; +typedef Optional OptionalStdString; +} //namespace DPL + +#endif /* DPL_OPTIONAL_TYPEDEFS_H */ + diff --git a/modules/core/include/dpl/platform.h b/modules/core/include/dpl/platform.h new file mode 100644 index 0000000..0049db4 --- /dev/null +++ b/modules/core/include/dpl/platform.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file platform.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + */ +#ifndef DPL_PLATFORM_H +#define DPL_PLATFORM_H + +// Use Features definition +// Use a particular optional platform service or third-party library +// +// Description : +// +// Author : () - +// #define USE__ (0 or 1) +#define USE(FEATURE) (defined USE_##FEATURE && USE_##FEATURE) + +// Description : Application side patch to use manual rotation feature in webkit +// Author : Jihoon Chung(jihoon.chung@samsung.com) - 10.26.2013 +#define USE_WEBKIT_MANUAL_ROTATION 1 + +// Description : Temporary patch about enable/disable webapp specific settings, especially for web-provider. +// Author : Jihoon Chung(jihoon.chung@samsung.com) - 11.09.2013 +#define USE_WEB_PROVIDER_EXCEPTION_IN_EWK_CONTEXT 1 + +// Description : Enhanced "progress bar" user experience. +// Show "progress bar" in "load,started" webkit callback to show earlier. +// Confirmed by webkit loader team. +// Author : Jihoon Chung(jihoon.chung@samsung.com) - 11.21.2013 +#define USE_WEBKIT_SHOW_PROGRESS_BAR_EARLIER 1 + +// Description : Webkit version-up +// Author : Jihoon Chung(jihoon.chung@samsung.com) - 01.14.2013 +#define USE_WEBKIT_UPVERSION 0 + +// Enable Features definition +// Turn on a specific feature of WRT +// +// Description : +// +// Author : () - +// #define ENABLE_ (0 or 1) +#define ENABLE(FEATURE) (defined ENABLE_##FEATURE && ENABLE_##FEATURE) + +// Description : Support onbeforeunload event +// Author : Jihoon Chung(jihoon.chung@samsung.com) - 11.15.2013 +#define ENABLE_JAVASCRIPT_ONBEFOREUNLOAD_EVENT 0 + +// Description : Support app scheme(app://) +// App scheme(app://) supports special scheme to packaged resources. +// Main reason of requirement is that enhance cross origin security and deprecate file scheme(file://). +// Author : Tomasz Iwanek(t.iwanek@samsung.com) - 11.16.2013 +#define ENABLE_APP_SCHEME 0 + +// Description : Custom user agent support by tizen widget setting +// Author : Tae-Jeong Lee (taejeong.lee@samsung.com) - 11.26.2013 +#define ENABLE_CUSTOM_USER_AGENT_SUPPORT 0 + +// Description : Support CORS(Cross-origin resource sharing) whitelisting +// Allow to use resource by trust origin. Basically, trust domain includes own app scheme(app://). +// Author : Tomasz Iwanek(t.iwanek@samsung.com) - 01.02.2014 +#define ENABLE_CORS_WHITELISTING 0 + +// Description : Support CSP(Content security policy) +// Author : Tomasz Iwanek(t.iwanek@samsung.com) - 01.03.2014 +#define ENABLE_CONTENT_SECURITY_POLICY 1 + +// Description : Enabling background decryption for encrypted resources +// Author : Tomasz Iwanek(t.iwanek@samsung.com) - 16.12.2013 +#define ENABLE_BACKGROUND_THREAD_DECRYPTION 0 + +// Description : Support allow-navigation +// Origin based navigation control of main resource. +// Author : Jihoon Chung (jihoon.chung@samsung.com) - 01.08.2014 +#define ENABLE_ALLOW_NAVIGATION 1 + +#endif // DPL_PLATFORM_H diff --git a/modules/core/include/dpl/preprocessor.h b/modules/core/include/dpl/preprocessor.h new file mode 100644 index 0000000..6fca34c --- /dev/null +++ b/modules/core/include/dpl/preprocessor.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file preprocessor.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file contains some usefull macros. + */ + +#ifndef DPL_PREPROCESSOR_H +#define DPL_PREPROCESSOR_H + +#define DPL_MACRO_CONCAT_IMPL(x, y) x##y +#define DPL_MACRO_CONCAT(x, y) DPL_MACRO_CONCAT_IMPL(x, y) + +#ifdef __COUNTER__ +#define DPL_ANONYMOUS_VARIABLE(name) DPL_MACRO_CONCAT(name, __COUNTER__) +#else +#define DPL_ANONYMOUS_VARIABLE(name) DPL_MACRO_CONCAT(name, __LINE__) +#endif + +#endif //DPL_PREPROCESSOR_H diff --git a/modules/core/include/dpl/read_write_mutex.h b/modules/core/include/dpl/read_write_mutex.h new file mode 100644 index 0000000..75d9f06 --- /dev/null +++ b/modules/core/include/dpl/read_write_mutex.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file read_write_mutex.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of read write mutex + */ +#ifndef DPL_READ_WRITE_MUTEX_H +#define DPL_READ_WRITE_MUTEX_H + +#include +#include +#include + +namespace DPL { +class ReadWriteMutex : + private Noncopyable +{ + public: + class ScopedReadLock : + private Noncopyable + { + private: + ReadWriteMutex *m_mutex; + + public: + ScopedReadLock(ReadWriteMutex *mutex); + virtual ~ScopedReadLock(); + }; + + class ScopedWriteLock : + private Noncopyable + { + private: + ReadWriteMutex *m_mutex; + + public: + ScopedWriteLock(ReadWriteMutex *mutex); + virtual ~ScopedWriteLock(); + }; + + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, DestroyFailed) + DECLARE_EXCEPTION_TYPE(Base, ReadLockFailed) + DECLARE_EXCEPTION_TYPE(Base, WriteLockFailed) + DECLARE_EXCEPTION_TYPE(Base, UnlockFailed) + }; + + private: + mutable pthread_rwlock_t m_rwlock; + + void ReadLock() const; + void WriteLock() const; + void Unlock() const; + + public: + explicit ReadWriteMutex(); + virtual ~ReadWriteMutex(); +}; +} // namespace DPL + +#endif // DPL_READ_WRITE_MUTEX_H diff --git a/modules/core/include/dpl/recursive_mutex.h b/modules/core/include/dpl/recursive_mutex.h new file mode 100644 index 0000000..e4744cc --- /dev/null +++ b/modules/core/include/dpl/recursive_mutex.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file recursive_mutex.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of recursive mutex + */ +#ifndef DPL_RECURSIVE_MUTEX_H +#define DPL_RECURSIVE_MUTEX_H + +#include +#include +#include + +namespace DPL { +class RecursiveMutex : + private Noncopyable +{ + public: + class ScopedLock : + private Noncopyable + { + private: + RecursiveMutex *m_mutex; + + public: + ScopedLock(RecursiveMutex *mutex); + virtual ~ScopedLock(); + }; + + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, DestroyFailed) + DECLARE_EXCEPTION_TYPE(Base, LockFailed) + DECLARE_EXCEPTION_TYPE(Base, UnlockFailed) + }; + + private: + mutable pthread_mutex_t m_mutex; + + void Lock() const; + void Unlock() const; + + public: + explicit RecursiveMutex(); + virtual ~RecursiveMutex(); +}; +} // namespace DPL + +#endif // DPL_RECURSIVE_MUTEX_H diff --git a/modules/core/include/dpl/scope_guard.h b/modules/core/include/dpl/scope_guard.h new file mode 100644 index 0000000..21a7b0c --- /dev/null +++ b/modules/core/include/dpl/scope_guard.h @@ -0,0 +1,111 @@ +/* + * Copyright 2013 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file scope_guard.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scope guard RAII + */ +#ifndef DPL_SCOPE_GUARD_H_ +#define DPL_SCOPE_GUARD_H_ + +#include +#include +#include +#include +#include + +namespace DPL { +template +class ScopeGuard +{ + public: + explicit ScopeGuard(const FunctionType& function) + : m_function{function}, + m_released{false} + {} + + explicit ScopeGuard(FunctionType&& function) + : m_function{std::move(function)}, + m_released{false} + {} + + ScopeGuard(ScopeGuard&& other) + : m_function{std::move(other.m_function)}, + m_released{other.m_released} + { + other.Release(); + } + + ScopeGuard(const ScopeGuard&) = delete; + + ~ScopeGuard() + { + if (!m_released) + { + Execute(); + } + } + + ScopeGuard& operator=(const ScopeGuard&) = delete; + + void Release() + { + m_released = true; + } + + void* operator new(size_t) = delete; + + private: + // FIXME change to noexcept when available + void Execute() throw() + { + m_function(); + } + + FunctionType m_function; + bool m_released; +}; + +template +inline ScopeGuard::type> +MakeScopeGuard(FunctionType&& function) +{ + return ScopeGuard::type>( + std::forward(function)); +} + +namespace detail { +enum class ScopeGuardOnExit {}; + +template +inline ScopeGuard::type> +operator+(detail::ScopeGuardOnExit, FunctionType&& function) +{ + return ScopeGuard::type>( + std::forward(function)); +} +} +} + +// FIXME provide support for compilers not supporting variadic macros; +// instead of using variadic macros (for compatibility) we could +// capture all by '&' (only referenced variables would be captured) +#define DPL_SCOPE_EXIT(...) \ + auto DPL_ANONYMOUS_VARIABLE(DPL_SCOPE_EXIT_STATE) \ + = ::DPL::detail::ScopeGuardOnExit() + [__VA_ARGS__]() + +#endif // DPL_SCOPE_GUARD_H_ diff --git a/modules/core/include/dpl/scoped_array.h b/modules/core/include/dpl/scoped_array.h new file mode 100644 index 0000000..1be91bd --- /dev/null +++ b/modules/core/include/dpl/scoped_array.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file scoped_ptr.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped array RAII + * + * This module is deprecated, please use standard C++11 feature: std::unique_ptr + */ +#ifndef DPL_SCOPED_ARRAY_H +#define DPL_SCOPED_ARRAY_H + +#include + +#include +#include +#include + +namespace DPL { +template +struct ScopedArrayPolicy +{ + typedef Class* Type; + static Type NullValue() + { + return NULL; + } + static void Destroy(Type ptr) + { + delete[] ptr; + } +}; + +template +class ScopedArray : public ScopedResource > +{ + typedef ScopedArrayPolicy Policy; + typedef ScopedResource BaseType; + + public: + explicit ScopedArray(Class *ptr = Policy::NullValue()) : BaseType(ptr) { } + + Class &operator [](std::ptrdiff_t k) const + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL array!"); + Assert(k >= 0 && "Negative array index"); + + return this->m_value[k]; + } +} DPL_DEPRECATED_WITH_MESSAGE("use standard C++11 feature: std::unique_ptr"); +} // namespace DPL + +#endif // DPL_SCOPED_PTR_H diff --git a/modules/core/include/dpl/scoped_close.h b/modules/core/include/dpl/scoped_close.h new file mode 100644 index 0000000..45477af --- /dev/null +++ b/modules/core/include/dpl/scoped_close.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file scoped_close.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped close RAII + */ +#ifndef DPL_SCOPED_CLOSE_H +#define DPL_SCOPED_CLOSE_H + +#include +#include +#include +#include +#include +#include + +namespace DPL { +struct ScopedClosePolicy +{ + typedef int Type; + static Type NullValue() + { + return -1; + } + static void Destroy(Type handle) + { + if (handle != -1) { + if (TEMP_FAILURE_RETRY(::fsync(handle)) == -1) { + std::string errString = GetErrnoString(); + LogPedantic("Failed to fsync scoped close error: " + << errString); + } + + if (::close(handle) == -1) { + std::string errString = GetErrnoString(); + LogPedantic("Failed to scoped close error: " + << errString); + } + } + } +}; + +class ScopedClose : public ScopedResource +{ + typedef ScopedClosePolicy Policy; + typedef ScopedResource BaseType; + typedef ScopedClosePolicy::Type Type; + + public: + explicit ScopedClose(Type handle = Policy::NullValue()) : + BaseType(handle) + { } +}; +} // namespace DPL + +#endif // DPL_SCOPED_CLOSE_H diff --git a/modules/core/include/dpl/scoped_dir.h b/modules/core/include/dpl/scoped_dir.h new file mode 100644 index 0000000..b10b4cc --- /dev/null +++ b/modules/core/include/dpl/scoped_dir.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file scoped_dir.h + * @author Iwanek Tomasz (t.iwanek@smasung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped directory existence + */ + +#ifndef DPL_SCOPED_DIR_H +#define DPL_SCOPED_DIR_H + +#include +#include +#include +#include + +namespace DPL { + +struct ScopedDirPolicy +{ + typedef std::string Type; + static Type NullValue(); + static void Destroy(Type ptr); +}; + +class ScopedDir : public ScopedResource +{ + typedef ScopedDirPolicy Policy; + typedef ScopedResource BaseType; + + public: + explicit ScopedDir(const std::string & str = Policy::NullValue(), mode_t mode = S_IRWXU|S_IRGRP|S_IXGRP); +}; +} // namespace DPL + +#endif // DPL_SCOPED_DIR_H diff --git a/modules/core/include/dpl/scoped_fclose.h b/modules/core/include/dpl/scoped_fclose.h new file mode 100644 index 0000000..b029803 --- /dev/null +++ b/modules/core/include/dpl/scoped_fclose.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file scoped_fclose.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped fclose RAII + */ +#ifndef DPL_SCOPED_FCLOSE_H +#define DPL_SCOPED_FCLOSE_H + +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +struct ScopedFClosePolicy +{ + typedef FILE* Type; + static Type NullValue() + { + return NULL; + } + static void Destroy(Type file) + { + if (file != NULL) { + // Try to flush first + if (TEMP_FAILURE_RETRY(fflush(file)) != 0) { + std::string errString = GetErrnoString(); + LogPedantic("Failed to fflush scoped fclose error: " + << errString); + } + + // fclose cannot be retried, try to close once + if (fclose(file) != 0) { + std::string errString = GetErrnoString(); + LogPedantic("Failed scoped fclose error: " << errString); + } + } + } +}; + +class ScopedFClose : public ScopedResource +{ + typedef ScopedFClosePolicy Policy; + typedef ScopedResource BaseType; + + public: + explicit ScopedFClose(FILE* argFileStream = Policy::NullValue()) : + BaseType(argFileStream) + {} +}; +} // namespace DPL + +#endif // DPL_SCOPED_FCLOSE_H diff --git a/modules/core/include/dpl/scoped_free.h b/modules/core/include/dpl/scoped_free.h new file mode 100644 index 0000000..7bebe39 --- /dev/null +++ b/modules/core/include/dpl/scoped_free.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file scoped_free.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped free RAII + */ + +#ifndef DPL_SCOPED_FREE_H +#define DPL_SCOPED_FREE_H + +#include +#include + +#include + +namespace DPL { +template +struct ScopedFreePolicy +{ + typedef Class* Type; + static Type NullValue() + { + return NULL; + } + static void Destroy(Type ptr) + { + free(ptr); + } +}; + +template +class ScopedFree : public ScopedResource > +{ + typedef ScopedFreePolicy Policy; + typedef ScopedResource BaseType; + + public: + explicit ScopedFree(Memory *ptr = Policy::NullValue()) : BaseType(ptr) { } +}; +} // namespace DPL + +#endif // DPL_SCOPED_FREE_H diff --git a/modules/core/include/dpl/scoped_gpointer.h b/modules/core/include/dpl/scoped_gpointer.h new file mode 100644 index 0000000..6ccfd9e --- /dev/null +++ b/modules/core/include/dpl/scoped_gpointer.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file scoped_gpointer.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped_gpointer + * + * This module is deprecated and may be removed in future. + */ + +#ifndef DPL_SCOPED_GPOINTER_H +#define DPL_SCOPED_GPOINTER_H + +#include +#include +#include +#include +#include + +namespace DPL { +struct ScopedGPointerPolicy +{ + typedef gpointer Type; + static Type NullValue() + { + return NULL; + } + static void Destroy(Type pointer) + { + if (pointer != NULL) { + g_object_unref(pointer); + } + } +}; + +template +class ScopedGPointer : public DPL::ScopedResource +{ + typedef ScopedGPointerPolicy Policy; + typedef DPL::ScopedResource BaseType; + + public: + explicit ScopedGPointer(typename Policy::Type pointer = + Policy::NullValue()) : + BaseType(pointer) + {} + + Class *operator->() const throw() + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL pointer!"); + return static_cast(this->m_value); + } + + Class & operator *() const throw() + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL pointer!"); + return *static_cast(this->m_value); + } +} DPL_DEPRECATED; +} // namespace DPL + +#endif // DPL_SCOPED_GPOINTER_H diff --git a/modules/core/include/dpl/scoped_ptr.h b/modules/core/include/dpl/scoped_ptr.h new file mode 100644 index 0000000..0a2d01d --- /dev/null +++ b/modules/core/include/dpl/scoped_ptr.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file scoped_ptr.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped pointer RAII + * + * This module is deprecated, please use standard C++11 feature: std::unique_ptr + */ +#ifndef DPL_SCOPED_PTR_H +#define DPL_SCOPED_PTR_H + +#include + +#include +#include +#include + +namespace DPL { +template +struct ScopedPtrPolicy +{ + typedef Class* Type; + static Type NullValue() + { + return NULL; + } + static void Destroy(Type ptr) + { + delete ptr; + } +}; + +template > +class ScopedPtr : public ScopedResource +{ + typedef ClassPolicy Policy; + typedef ScopedResource BaseType; + + public: + explicit ScopedPtr(Class *ptr = Policy::NullValue()) : BaseType(ptr) { } + + Class *operator->() const throw() + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL pointer!"); + return this->m_value; + } + + Class &operator *() const throw() + { + Assert(this->m_value != Policy::NullValue() && + "Dereference of scoped NULL pointer!"); + return *this->m_value; + } +} DPL_DEPRECATED_WITH_MESSAGE("use standard C++11 feature: std::unique_ptr"); +} // namespace DPL + +#endif // DPL_SCOPED_PTR_H diff --git a/modules/core/include/dpl/scoped_resource.h b/modules/core/include/dpl/scoped_resource.h new file mode 100644 index 0000000..63287da --- /dev/null +++ b/modules/core/include/dpl/scoped_resource.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file scoped_resource.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of scoped resource pattern + */ +#ifndef DPL_SCOPED_RESOURCE_H +#define DPL_SCOPED_RESOURCE_H + +#include + +namespace DPL { +template +class ScopedResource : + private Noncopyable +{ + public: + typedef typename ClassPolicy::Type ValueType; + typedef ScopedResource ThisType; + + protected: + ValueType m_value; + + public: + explicit ScopedResource(ValueType value) : m_value(value) { } + + ~ScopedResource() + { + ClassPolicy::Destroy(m_value); + } + + ValueType Get() const + { + return m_value; + } + + void Reset(ValueType value = ClassPolicy::NullValue()) + { + ClassPolicy::Destroy(m_value); + m_value = value; + } + + ValueType Release() + { + ValueType value = m_value; + m_value = ClassPolicy::NullValue(); + return value; + } + typedef ValueType ThisType::*UnknownBoolType; + + operator UnknownBoolType() const + { + return m_value == ClassPolicy::NullValue() ? + 0 : //0 is valid here because it converts to false + &ThisType::m_value; //it converts to true + } + + bool operator !() const + { + return m_value == ClassPolicy::NullValue(); + } +}; +} // namespace DPL + +#endif // DPL_SCOPED_RESOURCE_H diff --git a/modules/core/include/dpl/semaphore.h b/modules/core/include/dpl/semaphore.h new file mode 100644 index 0000000..0505621 --- /dev/null +++ b/modules/core/include/dpl/semaphore.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file semaphore.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of semaphore + */ +#ifndef DPL_SEMAPHORE_H +#define DPL_SEMAPHORE_H + +#include +#include +#include +#include + +namespace DPL { +class Semaphore : + private Noncopyable +{ + public: + class ScopedLock : + private Noncopyable + { + private: + Semaphore *m_semaphore; + + public: + explicit ScopedLock(Semaphore *semaphore); + ~ScopedLock(); + }; + + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, LockFailed) + DECLARE_EXCEPTION_TYPE(Base, UnlockFailed) + DECLARE_EXCEPTION_TYPE(Base, RemoveFailed) + }; + + private: + enum Type + { + Type_Unnamed, + Type_Named + }; + + Type m_type; + + mutable union + { + struct + { + sem_t handle; + } unnamed; + + struct + { + sem_t *handle; + char *name; + bool unlinkOnDestroy; + } named; + } m_semaphore; + + sem_t *InternalGet() const; + void InternalDestroy(); + + public: + /** + * decrement the semaphore counter + */ + void Lock() const; + + /** + * increment the semaphore counter + */ + void Unlock() const; + + /** + * Remove a named semaphore + * + * @param fileName Name of the semaphore + */ + static void Remove(const std::string &fileName); + + /** + * Open an unnamed semaphore + * + * @param maxLockCount Maximum number of threads allowed to enter semaphore + */ + explicit Semaphore(size_t maxLockCount); + + /** + * Open a named semaphore + * + * @param fileName Semaphore filename + * @param allowCreate Should non-existing semaphore be created + * @param maxLockCount Maximum number of threads allowed to enter semaphore + * @param permissions Semaphore file permissions + * @param unlinkOnDestroy Should semaphore file be deleted on destruction + */ + explicit Semaphore(const std::string &fileName, + bool allowCreate = true, + bool exclusiveCreate = false, + size_t maxLockCount = 1, + int permissions = 0600, + bool unlinkOnDestroy = false); + + /** + * Destroy a semaphore + */ + ~Semaphore(); +}; +} // namespace DPL + +#endif // DPL_SEMAPHORE_H diff --git a/modules/core/include/dpl/serialization.h b/modules/core/include/dpl/serialization.h new file mode 100644 index 0000000..d72c488 --- /dev/null +++ b/modules/core/include/dpl/serialization.h @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file serialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Interfaces and templates used for data serialization. + */ +#ifndef SERIALIZATION_H +#define SERIALIZATION_H + +#include +#include +#include +#include + +namespace DPL { +// Abstract data stream buffer +class IStream +{ + public: + virtual void Read(size_t num, void * bytes) = 0; + virtual void Write(size_t num, const void * bytes) = 0; + virtual ~IStream(){} +}; + +// Serializable interface +class ISerializable +{ + public: + /* ISerializable(){}; + * ISerializable(IStream&){}; */ + virtual void Serialize(IStream &) const = 0; + virtual ~ISerializable(){} +}; + +struct Serialization { + // serialization + // normal functions + + // ISerializable objects + static void Serialize(IStream& stream, const ISerializable& object) + { + object.Serialize(stream); + } + static void Serialize(IStream& stream, const ISerializable* const object) + { + object->Serialize(stream); + } + + // unsigned int + static void Serialize(IStream& stream, const unsigned value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream& stream, const unsigned* const value) + { + stream.Write(sizeof(*value), value); + } + + // int + static void Serialize(IStream& stream, const int value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream& stream, const int* const value) + { + stream.Write(sizeof(*value), value); + } + + // bool + static void Serialize(IStream& stream, const bool value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream& stream, const bool* const value) + { + stream.Write(sizeof(*value), value); + } + + // std::string + static void Serialize(IStream& stream, const std::string& str) + { + int length = str.size(); + stream.Write(sizeof(length), &length); + stream.Write(length, str.c_str()); + } + static void Serialize(IStream& stream, const std::string* const str) + { + int length = str->size(); + stream.Write(sizeof(length), &length); + stream.Write(length, str->c_str()); + } + + // STL templates + + // std::list + template + static void Serialize(IStream& stream, const std::list& list) + { + int length = list.size(); + stream.Write(sizeof(length), &length); + for (typename std::list::const_iterator list_iter = list.begin(); + list_iter != list.end(); list_iter++) + { + Serialize(stream, *list_iter); + } + } + template + static void Serialize(IStream& stream, const std::list* const list) + { + Serialize(stream, *list); + } + + // std::vector + template + static void Serialize(IStream& stream, const std::vector& vec) + { + int length = vec.size(); + stream.Write(sizeof(length), &length); + for (typename std::vector::const_iterator vec_iter = vec.begin(); + vec_iter != vec.end(); vec_iter++) + { + Serialize(stream, *vec_iter); + } + } + template + static void Serialize(IStream& stream, const std::vector* const vec) + { + Serialize(stream, *vec); + } + + // std::pair + template + static void Serialize(IStream& stream, const std::pair& p) + { + Serialize(stream, p.first); + Serialize(stream, p.second); + } + template + static void Serialize(IStream& stream, const std::pair* const p) + { + Serialize(stream, *p); + } + + // std::map + template + static void Serialize(IStream& stream, const std::map& map) + { + int length = map.size(); + stream.Write(sizeof(length), &length); + typename std::map::const_iterator it; + for (it = map.begin(); it != map.end(); ++it) { + Serialize(stream, (*it).first); + Serialize(stream, (*it).second); + } + } + template + static void Serialize(IStream& stream, const std::map* const map) + { + Serialize(stream, *map); + } +}; // struct Serialization + +struct Deserialization { + // deserialization + // normal functions + + // ISerializable objects + // T instead of ISerializable is needed to call proper constructor + template + static void Deserialize(IStream& stream, T& object) + { + object = T(stream); + } + template + static void Deserialize(IStream& stream, T*& object) + { + object = new T(stream); + } + + // unsigned int + static void Deserialize(IStream& stream, unsigned& value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream& stream, unsigned*& value) + { + value = new unsigned; + stream.Read(sizeof(*value), value); + } + + // int + static void Deserialize(IStream& stream, int& value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream& stream, int*& value) + { + value = new int; + stream.Read(sizeof(*value), value); + } + + // bool + static void Deserialize(IStream& stream, bool& value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream& stream, bool*& value) + { + value = new bool; + stream.Read(sizeof(*value), value); + } + + // std::string + static void Deserialize(IStream& stream, std::string& str) + { + int length; + stream.Read(sizeof(length), &length); + char * buf = new char[length + 1]; + stream.Read(length, buf); + buf[length] = 0; + str = std::string(buf); + delete[] buf; + } + static void Deserialize(IStream& stream, std::string*& str) + { + int length; + stream.Read(sizeof(length), &length); + char * buf = new char[length + 1]; + stream.Read(length, buf); + buf[length] = 0; + str = new std::string(buf); + delete[] buf; + } + + // STL templates + + // std::list + template + static void Deserialize(IStream& stream, std::list& list) + { + int length; + stream.Read(sizeof(length), &length); + for (int i = 0; i < length; ++i) { + T obj; + Deserialize(stream, obj); + list.push_back(obj); + } + } + template + static void Deserialize(IStream& stream, std::list*& list) + { + list = new std::list; + Deserialize(stream, *list); + } + + // std::vector + template + static void Deserialize(IStream& stream, std::vector& vec) + { + int length; + stream.Read(sizeof(length), &length); + for (int i = 0; i < length; ++i) { + T obj; + Deserialize(stream, obj); + vec.push_back(obj); + } + } + template + static void Deserialize(IStream& stream, std::vector*& vec) + { + vec = new std::vector; + Deserialize(stream, *vec); + } + + // std::pair + template + static void Deserialize(IStream& stream, std::pair& p) + { + Deserialize(stream, p.first); + Deserialize(stream, p.second); + } + template + static void Deserialize(IStream& stream, std::pair*& p) + { + p = new std::pair; + Deserialize(stream, *p); + } + + // std::map + template + static void Deserialize(IStream& stream, std::map& map) + { + int length; + stream.Read(sizeof(length), &length); + for (int i = 0; i < length; ++i) { + K key; + T obj; + Deserialize(stream, key); + Deserialize(stream, obj); + map[key] = obj; + } + } + template + static void Deserialize(IStream& stream, std::map*& map) + { + map = new std::map; + Deserialize(stream, *map); + } +}; // struct Deserialization +} // namespace DPL + +#endif // SERIALIZATION_H diff --git a/modules/core/include/dpl/shared_ptr.h b/modules/core/include/dpl/shared_ptr.h new file mode 100644 index 0000000..27f8b60 --- /dev/null +++ b/modules/core/include/dpl/shared_ptr.h @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file shared_ptr.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of shared pointer RAII + * + * This module is deprecated, please use standard C++11 feature: std::shared_ptr + */ +#ifndef DPL_SHARED_PTR_H +#define DPL_SHARED_PTR_H + +#include + +#include +#include +#include +#include +#include + +namespace DPL { +struct StaticPointerCastTag {}; +struct ConstPointerCastTag {}; +struct DynamicPointerCastTag {}; + +struct SharedCounter +{ + SharedCounter() : + ref(1) + {} + + Atomic ref; +}; + +template +class EnableSharedFromThis; + +template +inline void _Internal_AcceptSharedPtr(SharedCounter *counter, + Other *other, + EnableSharedFromThis *otherBase) +{ + otherBase->_Internal_AcceptSharedPtr(counter, other); +} + +struct AnyPointer +{ + template + AnyPointer(Other *) + {} +}; + +inline void _Internal_AcceptSharedPtr(SharedCounter *, AnyPointer, AnyPointer) +{} + +template +class SharedPtr +{ + public: + typedef Class ValueType; + typedef SharedPtr ThisType; + + private: + SharedCounter *m_counter; + Class *m_ptr; + + void AttachCounter(const SharedCounter *counter) + { + // Attention: R-Value const cast + m_counter = const_cast(counter); + + if (m_counter != NULL) { + ++m_counter->ref; + } + } + + void DetachCounter() + { + if (m_counter) { + if (!--m_counter->ref) { + delete m_ptr; + delete m_counter; + } + + m_counter = NULL; + m_ptr = NULL; + } + } + + public: + SharedPtr() : + m_counter(NULL), + m_ptr(NULL) + {} + + explicit SharedPtr(Class *ptr) : + m_counter(NULL), + m_ptr(ptr) + { + if (m_ptr != NULL) { + m_counter = new SharedCounter(); + _Internal_AcceptSharedPtr(m_counter, m_ptr, m_ptr); + } + } + + SharedPtr(const SharedPtr &other) : + m_counter(NULL), + m_ptr(other.m_ptr) + { + AttachCounter(other.m_counter); + } + + SharedPtr(SharedCounter *counter, Class *ptr) : + m_counter(NULL), + m_ptr(ptr) + { + AttachCounter(counter); + } + + template + friend class SharedPtr; + + template + SharedPtr(const SharedPtr &other, const StaticPointerCastTag &) : + m_counter(NULL), + m_ptr(NULL) + { + m_ptr = static_cast(other.m_ptr); + AttachCounter(other.m_counter); + } + + template + SharedPtr(const SharedPtr &other, const ConstPointerCastTag &) : + m_counter(NULL), + m_ptr(NULL) + { + m_ptr = const_cast(other.m_ptr); + AttachCounter(other.m_counter); + } + + template + SharedPtr(const SharedPtr &other, const DynamicPointerCastTag &) : + m_counter(NULL), + m_ptr(NULL) + { + Class *ptr = dynamic_cast(other.Get()); + + if (ptr == NULL) { + return; + } + + m_ptr = ptr; + AttachCounter(other.m_counter); + } + + virtual ~SharedPtr() + { + DetachCounter(); + } + + Class *Get() const + { + return m_counter == NULL ? NULL : m_ptr; + } + + Class *operator->() const + { + Assert(m_counter != NULL && "Dereference of shared NULL pointer!"); + return m_ptr; + } + + Class &operator *() const + { + Assert(m_counter != NULL && "Dereference of shared NULL pointer!"); + return *m_ptr; + } + + void Reset(Class *ptr = NULL) + { + DetachCounter(); + + if (ptr != NULL) { + m_ptr = ptr; + m_counter = new SharedCounter(); + _Internal_AcceptSharedPtr(m_counter, m_ptr, m_ptr); + } + } + + SharedPtr &operator=(const SharedPtr &other) + { + if (this != &other) { + DetachCounter(); + m_ptr = other.m_ptr; + AttachCounter(other.m_counter); + } + + return *this; + } + + Atomic::ValueType GetUseCount() const + { + if (m_counter == NULL) { + return Atomic::ValueType(0); + } + + return m_counter->ref; + } + + DPL_IMPLEMENT_BOOL_OPERATOR(ValueType, ThisType, m_counter, m_ptr) +} DPL_DEPRECATED_WITH_MESSAGE("use standard C++11 feature: std::shared_ptr"); + +template +SharedPtr StaticPointerCast(const SharedPtr &ptr) +{ + return SharedPtr(ptr, StaticPointerCastTag()); +} + +template +SharedPtr ConstPointerCast(const SharedPtr &ptr) +{ + return SharedPtr(ptr, ConstPointerCastTag()); +} + +template +SharedPtr DynamicPointerCast(const SharedPtr &ptr) +{ + return SharedPtr(ptr, DynamicPointerCastTag()); +} + +template +inline bool operator ==(const SharedPtr &first, + const SharedPtr &second) +{ + return first.Get() == second.Get(); +} + +template +inline bool operator !=(const SharedPtr &first, + const SharedPtr &second) +{ + return first.Get() != second.Get(); +} + +template +inline bool operator <(const SharedPtr &first, + const SharedPtr &second) +{ + return first.Get() < second.Get(); +} +template +inline bool operator >(const SharedPtr &first, + const SharedPtr &second) +{ + return first.Get() > second.Get(); +} + +template +inline bool operator <=(const SharedPtr &first, + const SharedPtr &second) +{ + return first.Get() <= second.Get(); +} + +template +inline bool operator >=(const SharedPtr &first, + const SharedPtr &second) +{ + return first.Get() >= second.Get(); +} +} // namespace DPL + +#endif // DPL_SHARED_PTR_H diff --git a/modules/core/include/dpl/single_instance.h b/modules/core/include/dpl/single_instance.h new file mode 100644 index 0000000..afcaf52 --- /dev/null +++ b/modules/core/include/dpl/single_instance.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file single_instance.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of single instance + */ +#ifndef DPL_SINGLE_INSTANCE_H +#define DPL_SINGLE_INSTANCE_H + +#include +#include +#include + +namespace DPL { +class SingleInstance : + private Noncopyable +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, LockError) + DECLARE_EXCEPTION_TYPE(Base, ReleaseError) + }; + + private: + bool m_locked; + int m_fdLock; + + public: + SingleInstance(); + virtual ~SingleInstance(); + + bool TryLock(const std::string &lockName); + void Release(); +}; +} // namespace DPL + +#endif // DPL_SINGLE_INSTANCE_H diff --git a/modules/core/include/dpl/singleton.h b/modules/core/include/dpl/singleton.h new file mode 100644 index 0000000..530f5c1 --- /dev/null +++ b/modules/core/include/dpl/singleton.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file singleton.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#ifndef DPL_SINGLETON_H +#define DPL_SINGLETON_H + +#include +#include +#include + +namespace DPL { +template +class Singleton : + private Class +{ + // + // Note: + // + // To remove posibility of instantiating directly Class, + // make Class' default constructor protected + // + + private: + Singleton() + {} + + typedef Optional OptionalThreadPtr; + + static Singleton &InternalInstance(); + + public: + virtual ~Singleton() + {} + + static Class &Instance(); +}; +} // namespace DPL + +#endif // DPL_SINGLETON_H diff --git a/modules/core/include/dpl/singleton_impl.h b/modules/core/include/dpl/singleton_impl.h new file mode 100644 index 0000000..12dbf32 --- /dev/null +++ b/modules/core/include/dpl/singleton_impl.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file singleton_impl.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#ifndef DPL_SINGLETON_IMPL_H +#define DPL_SINGLETON_IMPL_H + +/* + * WARNING! + * + * If some singleton's implementation uses another singletons implementation, + * those templates make the second singleton a dubleton. Be warned. Try to use + * singleton_safe_impl.h if possible. + */ + +namespace DPL { +template +Singleton& Singleton::InternalInstance() +{ + static Singleton instance; + return instance; +} + +template +Class &Singleton::Instance() +{ + Singleton& instance = Singleton::InternalInstance(); + return instance; +} +} // namespace DPL + +#define IMPLEMENT_SINGLETON(Type) \ + template DPL::Singleton&DPL::Singleton::InternalInstance(); \ + template Type & DPL::Singleton::Instance(); \ + +#endif // DPL_SINGLETON_IMPL_H diff --git a/modules/core/include/dpl/singleton_safe_impl.h b/modules/core/include/dpl/singleton_safe_impl.h new file mode 100644 index 0000000..c8923b7 --- /dev/null +++ b/modules/core/include/dpl/singleton_safe_impl.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file singleton_safe_impl.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#ifndef DPL_SINGLETON_SAFE_IMPL_H +#define DPL_SINGLETON_SAFE_IMPL_H + +#define IMPLEMENT_SAFE_SINGLETON(Class) \ + namespace DPL { \ + template<> \ + Singleton&Singleton::InternalInstance() \ + { \ + static Singleton instance; \ + return instance; \ + } \ + \ + template<> \ + Class & Singleton::Instance() \ + { \ + Singleton& instance = Singleton::InternalInstance(); \ + return instance; \ + } \ + \ + template Singleton&Singleton::InternalInstance(); \ + template Class & Singleton::Instance(); \ + } // namespace DPL + +#endif // DPL_SINGLETON_SAFE_IMPL_H diff --git a/modules/core/include/dpl/sstream.h b/modules/core/include/dpl/sstream.h new file mode 100644 index 0000000..aba4e0f --- /dev/null +++ b/modules/core/include/dpl/sstream.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file sstream.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief String stream typedefs + */ +#ifndef DPL_CORE_INCLUDE_SSTREAM_H_ +#define DPL_CORE_INCLUDE_SSTREAM_H_ + +#include +#include + +namespace DPL { +// @brief DPL IStringStream +typedef std::basic_istringstream IStringStream; + +// @brief DPL OStringStream +typedef std::basic_ostringstream OStringStream; +} //namespace DPL + +#endif // DPL_CORE_INCLUDE_SSTREAM_H_ diff --git a/modules/core/include/dpl/static_block.h b/modules/core/include/dpl/static_block.h new file mode 100644 index 0000000..62fae46 --- /dev/null +++ b/modules/core/include/dpl/static_block.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file static_block.h + * @author Iwanek Tomasz (t.iwanek@samsung.com) + * @version 1.0 + */ +#ifndef STATIC_BLOCK_H +#define STATIC_BLOCK_H + +#include + +//NOTE: order of static initialization of blocks is not specified + +// to be used only outside class of function scopes +#define STATIC_BLOCK_IMPL( UNIQUE ) \ + static void DPL_MACRO_CONCAT( _staticBlock , UNIQUE() ); \ + static int DPL_MACRO_CONCAT( _staticBlockInitAssurence , UNIQUE ) = []() -> int \ + { \ + (void) DPL_MACRO_CONCAT( _staticBlockInitAssurence , UNIQUE ); \ + DPL_MACRO_CONCAT( _staticBlock , UNIQUE() ); \ + return 0; \ + }(); \ + void DPL_MACRO_CONCAT( _staticBlock , UNIQUE() ) \ + +#define STATIC_BLOCK \ + STATIC_BLOCK_IMPL( __COUNTER__ ) \ + +//for class implementation +#define STATIC_BLOCK_CLASS( classname, methodname ) STATIC_BLOCK { classname::methodname(); } + +#endif // STATIC_BLOCK_H diff --git a/modules/core/include/dpl/string.h b/modules/core/include/dpl/string.h new file mode 100644 index 0000000..e4dc923 --- /dev/null +++ b/modules/core/include/dpl/string.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file string.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + */ +#ifndef DPL_STRING +#define DPL_STRING + +#include +#include +#include +#include +#include + +namespace DPL { +// @brief DPL string +typedef std::basic_string String; + +// @brief String exception class +class StringException +{ + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + + // @brief Invalid init for UTF8 to UTF32 converter + DECLARE_EXCEPTION_TYPE(Base, IconvInitErrorUTF8ToUTF32) + + // @brief Invalid taStdContainerinit for UTF32 to UTF32 converter + DECLARE_EXCEPTION_TYPE(Base, IconvInitErrorUTF32ToUTF8) + + // @brief Invalid conversion for UTF8 to UTF32 converter + DECLARE_EXCEPTION_TYPE(Base, IconvConvertErrorUTF8ToUTF32) + + // @brief Invalid conversion for UTF8 to UTF32 converter + DECLARE_EXCEPTION_TYPE(Base, IconvConvertErrorUTF32ToUTF8) + + // @brief Invalid ASCII character detected in FromASCII + DECLARE_EXCEPTION_TYPE(Base, InvalidASCIICharacter) + + // @brief Invalid ASCII character detected in FromASCII + DECLARE_EXCEPTION_TYPE(Base, ICUInvalidCharacterFound) +}; + +//!\brief convert ASCII string to DPL::String +String FromASCIIString(const std::string& aString); + +//!\brief convert UTF32 string to DPL::String +String FromUTF32String(const std::wstring& aString); + +//@brief Returns String object created from UTF8 string +//@param[in] aString input UTF-8 string +String FromUTF8String(const std::string& aString); + +//@brief Returns String content as std::string +std::string ToUTF8String(const String& aString); + +//@brief Compare two unicode strings +int StringCompare(const String &left, + const String &right, + bool caseInsensitive = false); + +//@brief Splits the string into substrings. +//@param[in] str Input string +//@param[in] delimiters array or string containing a sequence of substring +// delimiters. Can be also a single delimiter character. +//@param[in] it InserterIterator that is used to save the generated substrings. +template +void Tokenize(const StringType& str, + const Delimiters& delimiters, + InserterIterator it, + bool ignoreEmpty = false) +{ + typename StringType::size_type nextSearchStart = 0; + typename StringType::size_type pos; + typename StringType::size_type length; + + while (true) { + pos = str.find_first_of(delimiters, nextSearchStart); + length = + ((pos == StringType::npos) ? str.length() : pos) - nextSearchStart; + + if (!ignoreEmpty || length > 0) { + *it = str.substr(nextSearchStart, length); + it++; + } + + if (pos == StringType::npos) { + return; + } + + nextSearchStart = pos + 1; + } +} + +namespace Utils { + +template class ConcatFunc : public std::binary_function +{ +public: + explicit ConcatFunc(const T & val) : m_delim(val) {} + T operator()(const T & arg1, const T & arg2) const + { + return arg1 + m_delim + arg2; + } +private: + T m_delim; +}; + +} + +template +typename ForwardIterator::value_type Join(ForwardIterator begin, ForwardIterator end, typename ForwardIterator::value_type delim) +{ + typedef typename ForwardIterator::value_type value; + if(begin == end) return value(); + Utils::ConcatFunc func(delim); + ForwardIterator init = begin; + return std::accumulate(++begin, end, *init, func); +} + +template void TrimLeft(StringType & obj, typename StringType::const_pointer separators) +{ + obj.erase(0, obj.find_first_not_of(separators)); +} + +template void TrimRight(StringType & obj, typename StringType::const_pointer separators) +{ + obj.erase(obj.find_last_not_of(separators)+1); +} + +template void Trim(StringType & obj, typename StringType::const_pointer separators) +{ + TrimLeft(obj, separators); + TrimRight(obj, separators); +} + + +} //namespace DPL + +std::ostream& operator<<(std::ostream& aStream, const DPL::String& aString); + +#endif // DPL_STRING diff --git a/modules/core/include/dpl/task.h b/modules/core/include/dpl/task.h new file mode 100644 index 0000000..fa5f3a3 --- /dev/null +++ b/modules/core/include/dpl/task.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file task.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Radoslaw Wicik (r.wicik@samsung.com) + * @version 1.0 + * @brief Header file for abstaract task definition + */ +#ifndef DPL_TASK_H +#define DPL_TASK_H + +#include +#include +#include +#include +#include + +namespace DPL { + +class Task : + private Noncopyable +{ + public: + virtual ~Task() {} + + virtual bool NextStep() = 0; + virtual bool Abort() = 0; + virtual size_t GetStepCount() const = 0; +}; + +template +class TaskDecl : + public Task +{ + protected: + typedef void (Impl::*Step)(); + + private: + typedef std::list StepList; + + StepList m_steps; + StepList m_abortSteps; + typename StepList::iterator m_currentStep; + typename StepList::iterator m_nextStep; + bool m_switched; + + Impl *m_impl; + bool m_running; + + protected: + void AddStep(Step step) + { + Assert(!m_running && "AddStep is not allowed after calling NextStep!"); + Assert(m_steps.end() == std::find(m_steps.begin(), + m_steps.end(), + step) && + "The same step started twice is not supported"); + m_steps.push_back(step); + m_nextStep = m_steps.begin(); + } + + void AddAbortStep(Step step) + { + Assert( + !m_running && "AddAbortStep is not allowed after calling NextStep!"); + Assert(m_abortSteps.end() == + std::find(m_abortSteps.begin(), + m_abortSteps.end(), + step) && + "The same step started twice is not supported"); + m_abortSteps.push_front(step); + } + + void SwitchToStep(Step step) + { + /// @TODO There can be problem here if user sets the same method two + // times in task list. + typename StepList::iterator i = std::find(m_steps.begin(), + m_steps.end(), step); + Assert(i != m_steps.end()); + m_nextStep = i; + m_switched = true; + } + + Step GetCurrentStep() const + { + if (m_currentStep == m_steps.end()) { + return NULL; + } + + return *m_currentStep; + } + + public: + TaskDecl(Impl *impl) : + m_switched(false), + m_impl(impl), + m_running(false) + { + Assert(this == m_impl); + m_currentStep = m_steps.end(); + m_nextStep = m_steps.end(); + } + + bool NextStep() + { + m_running = true; + + Assert( + m_nextStep != m_steps.end() && + "Step list is empty or all steps done"); + + m_switched = false; + + Step call = *m_nextStep; + (*m_impl.*call)(); + + m_currentStep = m_nextStep; + + if (m_switched) { + return true; + } else { + return ++m_nextStep != m_steps.end(); + } + } + + bool Abort() + { + m_running = true; + + m_steps.clear(); + + if (m_abortSteps.empty()) { + return false; + } + + FOREACH(it, m_abortSteps) + m_steps.push_back(*it); + + m_nextStep = m_steps.begin(); + + m_abortSteps.clear(); + + return true; + } + + size_t GetStepCount() const + { + return static_cast(m_steps.size()); + } +}; +} // namespace DPL + +#endif // DPL_TASK_H diff --git a/modules/core/include/dpl/thread.h b/modules/core/include/dpl/thread.h new file mode 100644 index 0000000..a0040eb --- /dev/null +++ b/modules/core/include/dpl/thread.h @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of thread + */ +#ifndef DPL_THREAD_H +#define DPL_THREAD_H + +#include +//#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +class Thread : + private Noncopyable, + public WaitableHandleWatchSupport +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, DestroyFailed) + DECLARE_EXCEPTION_TYPE(Base, RunFailed) + DECLARE_EXCEPTION_TYPE(Base, QuitFailed) + DECLARE_EXCEPTION_TYPE(Base, UnmanagedThread) + }; + + typedef void (*EventDeleteProc)(void *event, void *userParam); + typedef void (*EventDispatchProc)(void *event, void *userParam); + + protected: + /** + * Main thread entry + * The method is intended to be overloaded with custom code. + * Default implementation just executes Exec method to process + * all thread exents + */ + virtual int ThreadEntry(); + + /** + * Start processing of thread events + */ + int Exec(); + + private: + struct InternalEvent + { + void *event; + void *userParam; + EventDispatchProc eventDispatchProc; + EventDeleteProc eventDeleteProc; + + InternalEvent(void *eventArg, + void *userParamArg, + EventDispatchProc eventDispatchProcArg, + EventDeleteProc eventDeleteProcArg) : + event(eventArg), + userParam(userParamArg), + eventDispatchProc(eventDispatchProcArg), + eventDeleteProc(eventDeleteProcArg) + {} + }; + + struct InternalTimedEvent : + InternalEvent + { + unsigned long dueTimeMiliseconds; + unsigned long registerTimeMiliseconds; + + InternalTimedEvent(void *eventArg, + void *userParamArg, + unsigned long dueTimeMilisecondsArg, + unsigned long registerTimeMilisecondsArg, + EventDispatchProc eventDispatchProcArg, + EventDeleteProc eventDeleteProcArg) : + InternalEvent(eventArg, + userParamArg, + eventDispatchProcArg, + eventDeleteProcArg), + dueTimeMiliseconds(dueTimeMilisecondsArg), + registerTimeMiliseconds(registerTimeMilisecondsArg) + {} + + bool operator<(const InternalTimedEvent &other) + { + return registerTimeMiliseconds + dueTimeMiliseconds > + other.registerTimeMiliseconds + other.dueTimeMiliseconds; + } + }; + + // Internal event list + typedef std::list InternalEventList; + + // Internal timed event list + typedef std::vector InternalTimedEventVector; + + // State managment + pthread_t m_thread; + volatile bool m_abandon; + volatile bool m_running; + Mutex m_stateMutex; + WaitableEvent m_quitEvent; + + // Event processing + Mutex m_eventMutex; + InternalEventList m_eventList; + WaitableEvent m_eventInvoker; + + // Timed events processing + Mutex m_timedEventMutex; + InternalTimedEventVector m_timedEventVector; + WaitableEvent m_timedEventInvoker; + + // WaitableHandleWatchSupport + virtual Thread *GetInvokerThread(); + virtual void HandleDirectInvoker(); + bool m_directInvoke; + + // Internals + unsigned long GetCurrentTimeMiliseconds() const; + void ProcessEvents(); + void ProcessTimedEvents(); + + static void *StaticThreadEntry(void *param); + + public: + explicit Thread(); + virtual ~Thread(); + + /** + * Run thread. Does nothing if thread is already running + */ + void Run(); + + /** + * Send quit message to thread and wait for its end + * Does nothing is thread is not running + */ + void Quit(); + + /** + * Checks if current thread is main one + * Returns true if it is main program thread, false otherwise + */ + static bool IsMainThread(); + + /** + * Current thread retrieval + * Returns DPL thread handle or NULL if it is main program thread + */ + static Thread *GetCurrentThread(); + + /** + * Low-level event push, usually used only by EventSupport + */ + void PushEvent(void *event, + EventDispatchProc eventDispatchProc, + EventDeleteProc eventDeleteProc, + void *userParam); + + /** + * Low-level timed event push, usually used only by EventSupport + */ + void PushTimedEvent(void *event, + double dueTimeSeconds, + EventDispatchProc eventDispatchProc, + EventDeleteProc eventDeleteProc, + void *userParam); + + /** + * Sleep for a number of seconds + */ + static void Sleep(uint64_t seconds); + + /** + * Sleep for a number of miliseconds + */ + static void MiliSleep(uint64_t miliseconds); + + /** + * Sleep for a number of microseconds + */ + static void MicroSleep(uint64_t microseconds); + + /** + * Sleep for a number of nanoseconds + */ + static void NanoSleep(uint64_t nanoseconds); +}; + +extern bool g_TLSforMainCreated; + +// In case of using TLV in main thread, pthread_exit(NULL) has to be called in +// this thread explicitly. +// On the other hand, possibly, because of the kernel bug, there exist +// a problem, if any other thread than main exist during pthread_exit call +// (process can become non-responsive) +// TODO further investigation is required. +template +class ThreadLocalVariable : + public Noncopyable +{ + public: + typedef Type ValueType; + + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, NullReference) + DECLARE_EXCEPTION_TYPE(Base, KeyCreateFailed) + }; + + private: + pthread_key_t m_key; + + struct ManagedValue + { + ValueType value; + Optional guardKey; + }; + + static void MainThreadExitClean() + { + // There is a possible bug in kernel. If this function is called + // before ALL threads are closed, process will hang! + // Because of that, by default this function has to be called in well + // known "threads state". + + // pthread_exit(NULL); + } + + static void InternalDestroy(void *specific) + { + // Destroy underlying type + ManagedValue *instance = static_cast(specific); + if (instance->guardKey.IsNull()) { + delete instance; + } else { + int result = pthread_setspecific(*(instance->guardKey), instance); + + Assert(result == 0 && + "Failed to set thread local variable"); + } + } + + Type &Reference(bool allowInstantiate = false) + { + ManagedValue *instance = + static_cast(pthread_getspecific(m_key)); + + if (!instance) { + // Check if it is allowed to instantiate + if (!allowInstantiate) { + Throw(typename Exception::NullReference); + } + + // checking, if specific data is created for Main thread + // If yes, pthread_exit(NULL) is required + if (!g_TLSforMainCreated) { + if (Thread::IsMainThread()) { + g_TLSforMainCreated = true; + atexit(&MainThreadExitClean); + } + } + + // Need to instantiate underlying type + instance = new ManagedValue(); + + int result = pthread_setspecific(m_key, instance); + + Assert(result == 0 && + "Failed to set thread local variable"); + } + + return instance->value; + } + + public: + ThreadLocalVariable() + { + int result = pthread_key_create(&m_key, &InternalDestroy); + if (result != 0) { + ThrowMsg(typename Exception::KeyCreateFailed, + "Failed to allocate thread local variable: " << result); + } + } + + ~ThreadLocalVariable() + { + pthread_key_delete(m_key); + } + + Type &operator=(const Type &other) + { + Type &reference = Reference(true); + reference = other; + return reference; + } + + bool IsNull() const + { + return pthread_getspecific(m_key) == NULL; + } + + Type& operator*() + { + return Reference(); + } + + const Type& operator*() const + { + return Reference(); + } + + const Type* operator->() const + { + return &Reference(); + } + + Type* operator->() + { + return &Reference(); + } + + bool operator!() const + { + return IsNull(); + } + + void Reset() + { + ManagedValue *specific = + static_cast(pthread_getspecific(m_key)); + + if (!specific) { + return; + } + + // TODO Should be an assert? is it developers fault to Reset Guarded + // value? + specific->guardKey = Optional::Null; + + InternalDestroy(specific); + + int result = pthread_setspecific(m_key, NULL); + + Assert(result == 0 && + "Failed to reset thread local variable"); + } + + // GuardValue(true) allows to defer destroy (by pthread internal + // functionality) thread specific value until GuardValue(false) will be + // called. + void GuardValue(bool guard) + { + ManagedValue *instance = + static_cast(pthread_getspecific(m_key)); + + Assert(instance && "Failed to get the value"); + + instance->guardKey = guard ? m_key : Optional::Null; + } +}; +} // namespace DPL + +#endif // DPL_THREAD_H diff --git a/modules/core/include/dpl/type_list.h b/modules/core/include/dpl/type_list.h new file mode 100644 index 0000000..88afaf2 --- /dev/null +++ b/modules/core/include/dpl/type_list.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file type_list.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Generic type list template + */ +#ifndef DPL_TYPE_LIST_H +#define DPL_TYPE_LIST_H + +#include + +namespace DPL { +class TypeListGuard +{ + public: + template + struct Element + { + struct ERROR_TypeListElementIndexIsOutOfBounds; + typedef ERROR_TypeListElementIndexIsOutOfBounds Type; + }; + + static const size_t Size = 0; +}; + +template +class TypeList +{ + private: + class DummyClass + {}; + + template + struct TypeCounter : public TypeCounter + {}; + + template + struct TypeCounter + { + static const size_t Size = Enum; + }; + + public: + typedef TailType Tail; + typedef HeadType Head; + typedef TypeList ThisType; + + template + struct Element + { + typedef typename TailType::template Element::Type Type; + }; + + template + struct Element<0, DummyType> + { + typedef HeadType Type; + }; + + template + struct Contains + { + typedef typename TailType::template Contains::Yes Yes; + }; + + template + struct Contains + { + typedef int Yes; + }; + + static const size_t Size = TypeCounter::Size; +}; + +template +struct TypeListDecl +{ + typedef TypeList::Type> Type; +}; + +template<> +struct TypeListDecl +{ + typedef TypeListGuard Type; +}; +} // namespace DPL + +#endif // DPL_TYPE_LIST_H diff --git a/modules/core/include/dpl/union_cast.h b/modules/core/include/dpl/union_cast.h new file mode 100644 index 0000000..3f499a4 --- /dev/null +++ b/modules/core/include/dpl/union_cast.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file union_cast.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for union cast + */ +#ifndef DPL_UNION_CAST_H +#define DPL_UNION_CAST_H + +#include + +namespace DPL { +template +TargetType union_cast(const SourceType &data) +{ + union + { + SourceType source; + TargetType target; + } cast; + + std::memset(&cast, 0, sizeof(cast)); + + cast.source = data; + return cast.target; +} +} // namespace DPL + +#endif // DPL_UNION_CAST_H diff --git a/modules/core/include/dpl/waitable_event.h b/modules/core/include/dpl/waitable_event.h new file mode 100644 index 0000000..364bc5c --- /dev/null +++ b/modules/core/include/dpl/waitable_event.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_event.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable event + */ +#ifndef DPL_WAITABLE_EVENT_H +#define DPL_WAITABLE_EVENT_H + +#include +#include +#include +#include + +namespace DPL { +class WaitableEvent : + private Noncopyable +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, DestroyFailed) + DECLARE_EXCEPTION_TYPE(Base, SignalFailed) + DECLARE_EXCEPTION_TYPE(Base, ResetFailed) + }; + + private: + int m_pipe[2]; + + public: + WaitableEvent(); + virtual ~WaitableEvent(); + + WaitableHandle GetHandle() const; + + void Signal() const; + void Reset() const; +}; +} // namespace DPL + +#endif // DPL_WAITABLE_EVENT_H diff --git a/modules/core/include/dpl/waitable_handle.h b/modules/core/include/dpl/waitable_handle.h new file mode 100644 index 0000000..9864f78 --- /dev/null +++ b/modules/core/include/dpl/waitable_handle.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_handle.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of waitable handle + */ +#ifndef DPL_WAITABLE_HANDLE_H +#define DPL_WAITABLE_HANDLE_H + +#include +#include +#include + +namespace DPL { +/** + * Waitable unix wait handle definition + */ +typedef int WaitableHandle; + +/** + * Waitable handle list + */ +typedef std::vector WaitableHandleList; + +/** + * Wait mode + */ +class WaitMode +{ + public: + enum Type + { + Read, ///< Wait for readability state changes + Write ///< Wait for writability state changes + }; +}; + +/** + * Waitable handle list ex + */ +typedef std::vector > WaitableHandleListEx; + +/** + * Waitable handle index list + */ +typedef std::vector WaitableHandleIndexList; + +/** + * Wait exceptions + */ +DECLARE_EXCEPTION_TYPE(DPL::Exception, WaitFailed) + +/** + * Wait for single handle readability + * Convience function. + * + * @return Signaled waitable handle index list + * @throw WaitFailed Fatal error occurred while waiting for signal + */ +WaitableHandleIndexList WaitForSingleHandle( + WaitableHandle handle, + unsigned long miliseconds = + 0xFFFFFFFF); + +/** + * Wait for single handle + * Convience function. + * + * @return Signaled waitable handle index list + * @throw WaitFailed Fatal error occurred while waiting for signal + */ +WaitableHandleIndexList WaitForSingleHandle( + WaitableHandle handle, + WaitMode::Type mode, + unsigned long miliseconds = + 0xFFFFFFFF); + +/** + * Wait for multiple handles readability + * + * @return Signaled waitable handle index list + * @throw WaitFailed Fatal error occurred while waiting for signal + */ +WaitableHandleIndexList WaitForMultipleHandles( + const WaitableHandleList &handleList, + unsigned long miliseconds = 0xFFFFFFFF); + +/** + * Wait for multiple handles readability + * + * @return Signaled waitable handle index list + * @throw WaitFailed Fatal error occurred while waiting for signal + */ +WaitableHandleIndexList WaitForMultipleHandles( + const WaitableHandleListEx &handleListEx, + unsigned long miliseconds = 0xFFFFFFFF); +} // namespace DPL + +#endif // DPL_WAITABLE_HANDLE_H diff --git a/modules/core/include/dpl/waitable_handle_watch_support.h b/modules/core/include/dpl/waitable_handle_watch_support.h new file mode 100644 index 0000000..ac0987f --- /dev/null +++ b/modules/core/include/dpl/waitable_handle_watch_support.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_handle_watch_support.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable handle watch + * support + */ +#ifndef DPL_WAITABLE_HANDLE_WATCH_SUPPORT_H +#define DPL_WAITABLE_HANDLE_WATCH_SUPPORT_H + +#include +#include +#include +#include +#include +#include + +namespace DPL { +class Thread; + +class WaitableHandleWatchSupport +{ + public: + class WaitableHandleListener + { + public: + virtual ~WaitableHandleListener() {} + + virtual void OnWaitableHandleEvent(WaitableHandle waitableHandle, + WaitMode::Type mode) = 0; + }; + + protected: + // Invoker waitable handle + // Signaled by Add/Remove methods + // After being signaled one must call Handle invoke to reset invoker + WaitableHandle WaitableInvokerHandle() const; + + // Waitable handle ex list + WaitableHandleListEx WaitableWatcherHandles() const; + + // Perform actions for signaled waitable handle + // Called in execution context, after + void HandleWatcher(WaitableHandle waitableHandle, WaitMode::Type mode); + + // Perform actions after invoker was signaled + void InvokerFinished(); + + // Get invoker context + virtual Thread *GetInvokerThread() = 0; + + // Invoke direct invoker + virtual void HandleDirectInvoker() = 0; + + private: + // Waitable event watchers + struct WaitableHandleWatcher + { + WaitableHandleListener *listener; + WaitMode::Type mode; + + WaitableHandleWatcher(WaitableHandleListener *l, WaitMode::Type m) : + listener(l), + mode(m) + {} + }; + + typedef std::list WaitableHandleListenerList; + + struct WaitableHandleWatchers + { + WaitableHandleListenerList listeners; + size_t readListenersCount; + size_t writeListenersCount; + + WaitableHandleWatchers() : + readListenersCount(0), + writeListenersCount(0) + {} + }; + + typedef std::map WaitableHandleWatchersMap; + + // Waitable event watch support + mutable RecursiveMutex m_watchersMutex; + WaitableHandleWatchersMap m_watchersMap; + WaitableEvent m_watchersInvoker; + WaitableEvent m_watchersInvokerCommit; + + // Invoke call + void CommitInvoker(); + + public: + /** + * Constructor + */ + explicit WaitableHandleWatchSupport(); + + /** + * Destructor + */ + virtual ~WaitableHandleWatchSupport(); + + /** + * Adds listener for specific waitable event + * + * @param[in] listener Listener to attach + * @param[in] waitableHandle Waitable handle to listen for changes + * @param[in] mode Type of changes to listen to + * @return none + * @see WaitMode::Type + */ + void AddWaitableHandleWatch(WaitableHandleListener *listener, + WaitableHandle waitableHandle, + WaitMode::Type mode); + + /** + * Remove listener for specific waitable event + * + * @param[in] listener Listener to detach + * @param[in] waitableHandle Waitable handle to unlisten for changes + * @param[in] mode Type of changes to unlisten to + * @return none + * @see WaitMode::Type + */ + void RemoveWaitableHandleWatch(WaitableHandleListener *listener, + WaitableHandle waitableHandle, + WaitMode::Type mode); + + /** + * Retrieve inherited context + * + * @return Inherited waitable handle watch support + */ + static WaitableHandleWatchSupport *InheritedContext(); +}; +} // namespace DPL + +#endif // DPL_WAITABLE_HANDLE_WATCH_SUPPORT_H diff --git a/modules/core/include/dpl/workaround.h b/modules/core/include/dpl/workaround.h new file mode 100644 index 0000000..19c26ef --- /dev/null +++ b/modules/core/include/dpl/workaround.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file workaround.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of workaround + */ +#ifndef DPL_WORKAROUND_H +#define DPL_WORKAROUND_H + +/** + * Define following macro to track invalid waitable handles + * in WaitForSingle/WaitForMultiple functions + */ +#define DPL_ENABLE_WAITABLE_HANDLE_BADF_CHECK + +/** + * Define following macro to enable workaround for problem + * with GLIB loop integration and EBADF error handling + */ +#define DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND + +/** + * Define following macro to enable workaround for problem + * with invalid conversions in htons/ntohs macros + */ +#define DPL_ENABLE_HTONS_NTOHS_I386_WORKAROUND + +#endif // DPL_WORKAROUND_H diff --git a/modules/core/include/dpl/zip_input.h b/modules/core/include/dpl/zip_input.h new file mode 100644 index 0000000..b364fe4 --- /dev/null +++ b/modules/core/include/dpl/zip_input.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file zip_input.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of zip input + */ +#ifndef DPL_ZIP_INPUT_H +#define DPL_ZIP_INPUT_H + +#include +#include +#include +#include +#include +#include + +namespace DPL { +class ZipInput : + private Noncopyable +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, ReadGlobalInfoFailed) + DECLARE_EXCEPTION_TYPE(Base, ReadGlobalCommentFailed) + DECLARE_EXCEPTION_TYPE(Base, SeekFileFailed) + DECLARE_EXCEPTION_TYPE(Base, FileInfoFailed) + DECLARE_EXCEPTION_TYPE(Base, OpenFileFailed) + DECLARE_EXCEPTION_TYPE(Base, ReadFileFailed) + }; + + typedef std::pair FileHandle; + + struct FileInfo + { + // File handle + FileHandle handle; + + // File name and comment + std::string name; + std::string comment; + + // File information + off64_t compressedSize; //< compressed size + off64_t uncompressedSize; //< uncompressed size + + FileInfo() : + handle(), + name(), + comment(), + compressedSize(0), + uncompressedSize(0) + {} + + FileInfo(const FileHandle &handleArg, + const std::string &nameArg, + const std::string &commentArg, + const off64_t &compressedSizeArg, + const off64_t &uncompressedSizeArg) : + handle(handleArg), + name(nameArg), + comment(commentArg), + compressedSize(compressedSizeArg), + uncompressedSize(uncompressedSizeArg) + {} + }; + + class File : + public DPL::AbstractInput + { + private: + void *m_file; + + friend class ZipInput; + File(class Device *device, FileHandle handle); + + public: + ~File(); + + virtual DPL::BinaryQueueAutoPtr Read(size_t size); + }; + + private: + class Device * m_device; + void *m_masterFile; + + size_t m_numberOfFiles; + size_t m_globalCommentSize; + std::string m_globalComment; + size_t m_totalUncompressedSize; + + // At least cache handles + typedef std::vector FileInfoList; + FileInfoList m_fileInfos; + + void ReadGlobalInfo(void *masterFile); + void ReadGlobalComment(void *masterFile); + void ReadInfos(void *masterFile); + + public: + typedef FileInfoList::const_iterator const_iterator; + typedef FileInfoList::const_reverse_iterator const_reverse_iterator; + typedef FileInfoList::size_type size_type; + + public: + /** + * Open zip file from file + */ + explicit ZipInput(const std::string &fileName); + + /** + * Destructor + */ + ~ZipInput(); + + // Iterators + const_iterator begin() const; + const_iterator end() const; + + const_reverse_iterator rbegin() const; + const_reverse_iterator rend() const; + + // Size, empty + size_type size() const; + bool empty() const; + + /** + * Open a binary file for given file name + * + * @return file object + * @param[in] fileName Zip file name to open + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @exception SteamOpenFailed Cannot find file with given handle + * @see BinaryQueue::BufferDeleterFree + */ + File *OpenFile(const std::string &fileName); + + /** + * Get archive global comment + * + * @return Global archive comment + */ + const std::string &GetGlobalComment() const; + size_t GetTotalUncompressedSize() const; +}; +} // namespace DPL + +#endif // DPL_ZIP_INPUT_H diff --git a/modules/core/src/DESCRIPTION b/modules/core/src/DESCRIPTION new file mode 100644 index 0000000..9043c93 --- /dev/null +++ b/modules/core/src/DESCRIPTION @@ -0,0 +1 @@ +Source files diff --git a/modules/core/src/abstract_waitable_input_adapter.cpp b/modules/core/src/abstract_waitable_input_adapter.cpp new file mode 100644 index 0000000..a802a7f --- /dev/null +++ b/modules/core/src/abstract_waitable_input_adapter.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input_adapter.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract waitable input + * adapter + */ +#include +#include + +namespace DPL { +AbstractWaitableInputAdapter::AbstractWaitableInputAdapter(AbstractInput *input) + : + m_input(input) +{ + m_waitableEvent.Signal(); +} + +BinaryQueueAutoPtr AbstractWaitableInputAdapter::Read(size_t size) +{ + return m_input->Read(size); +} + +WaitableHandle AbstractWaitableInputAdapter::WaitableReadHandle() const +{ + return m_waitableEvent.GetHandle(); +} +} // namespace DPL diff --git a/modules/core/src/abstract_waitable_input_output_adapter.cpp b/modules/core/src/abstract_waitable_input_output_adapter.cpp new file mode 100644 index 0000000..e432b31 --- /dev/null +++ b/modules/core/src/abstract_waitable_input_output_adapter.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_input_output_adapter.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract waitable input + * output adapter + */ +#include +#include + +namespace DPL { +AbstractWaitableInputOutputAdapter::AbstractWaitableInputOutputAdapter( + AbstractInputOutput *inputOutput) : + AbstractWaitableInputAdapter(inputOutput), + AbstractWaitableOutputAdapter(inputOutput) +{} +} // namespace DPL diff --git a/modules/core/src/abstract_waitable_output_adapter.cpp b/modules/core/src/abstract_waitable_output_adapter.cpp new file mode 100644 index 0000000..82c2347 --- /dev/null +++ b/modules/core/src/abstract_waitable_output_adapter.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_waitable_output_adapter.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract waitable output + * adapter + */ +#include +#include + +namespace DPL { +AbstractWaitableOutputAdapter::AbstractWaitableOutputAdapter( + AbstractOutput *output) : + m_output(output) +{ + m_waitableEvent.Signal(); +} + +size_t AbstractWaitableOutputAdapter::Write(const BinaryQueue &buffer, + size_t bufferSize) +{ + return m_output->Write(buffer, bufferSize); +} + +WaitableHandle AbstractWaitableOutputAdapter::WaitableWriteHandle() const +{ + return m_waitableEvent.GetHandle(); +} +} // namespace DPL diff --git a/modules/core/src/address.cpp b/modules/core/src/address.cpp new file mode 100644 index 0000000..34c8861 --- /dev/null +++ b/modules/core/src/address.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file address.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of address + */ +#include +#include +#include +#include + +namespace DPL { +Address::Address() : + m_port(0) +{} + +Address::Address(const std::string &address) : + m_address(address), + m_port(0) +{} + +Address::Address(const std::string &address, unsigned short port) : + m_address(address), + m_port(port) +{} + +Address::~Address() +{} + +std::string Address::GetAddress() const +{ + return m_address; +} + +unsigned short Address::GetPort() const +{ + return m_port; +} + +std::string Address::ToString() const +{ + std::ostringstream out; + out << m_address << ":" << m_port; + return out.str(); +} + +bool Address::operator<(const Address &addr) const +{ + return ToString() < addr.ToString(); +} +} // namespace DPL diff --git a/modules/core/src/application.cpp b/modules/core/src/application.cpp new file mode 100644 index 0000000..b2c9cc0 --- /dev/null +++ b/modules/core/src/application.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file application.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC application support + */ +#include +#include +#include + +namespace // anonymous +{ +static DPL::Application *g_application = NULL; +} // namespace anonymous + +namespace DPL { +int Application::app_create(void *data) +{ + Application *This = static_cast(data); + This->OnCreate(); + return 0; +} + +int Application::app_terminate(void *data) +{ + Application *This = static_cast(data); + This->OnTerminate(); + return 0; +} + +int Application::app_pause(void *data) +{ + Application *This = static_cast(data); + This->OnPause(); + return 0; +} + +int Application::app_resume(void *data) +{ + Application *This = static_cast(data); + This->OnResume(); + return 0; +} + +int Application::app_reset(bundle *b, void *data) +{ + Application *This = static_cast(data); + This->OnReset(b); + return 0; +} + +Application::Application(int argc, char** argv, + const std::string& applicationName, + bool showMainWindow) : + m_argc(argc), + m_argv(argv), + m_applicationName(applicationName), + m_mainWindowVisible(showMainWindow) +{ + if (g_application != NULL) { + ThrowMsg(Exception::TooManyInstances, + "Only single instance of Application allowed at one time!"); + } + + g_application = this; +} + +Application::~Application() +{ + g_application = NULL; +} + +int Application::Exec() +{ + LogPedantic("Starting application framework..."); + + struct appcore_ops ops; + ops.create = app_create; + ops.terminate = app_terminate; + ops.pause = app_pause; + ops.resume = app_resume; + ops.reset = app_reset; + ops.data = this; + + int result = appcore_efl_main( + m_applicationName.c_str(), &m_argc, &m_argv, &ops); + + LogPedantic("Exited application framework"); + + return result; +} + +void Application::OnCreate() +{ + LogPedantic("On application create"); +} + +void Application::OnStart() +{ + LogPedantic("On application start"); +} + +void Application::OnStop() +{ + LogPedantic("On application stop"); +} + +void Application::OnResume() +{ + LogPedantic("On application resume"); +} + +void Application::OnPause() +{ + LogPedantic("On application pause"); +} + +void Application::OnRelaunch() +{ + LogPedantic("On application relaunch"); +} + +void Application::OnReset(bundle *b) +{ + (void)b; + LogPedantic("On application reset"); +} + +void Application::OnTerminate() +{ + LogPedantic("On application terminate"); +} + +void Application::OnLowMemory() +{ + LogPedantic("On application low memory"); +} + +void Application::OnLowBattery() +{ + LogPedantic("On application low battery"); +} + +void Application::OnLanguageChanged() +{ + LogPedantic("On application language changed"); +} + +void Application::Quit() +{ + elm_exit(); +} + +DPL::Atomic ApplicationExt::m_useCount(0); + +ApplicationExt::ApplicationExt(int argc, + char** argv, + const std::string& applicationName, + bool showMainWindow) : + Application(argc, argv, applicationName, showMainWindow) +{} + +ApplicationExt::~ApplicationExt() +{} + +int ApplicationExt::Exec() +{ + if (0 == m_useCount.CompareAndExchange(0, 1)) { + return Application::Exec(); + } else { + elm_run(); + } + return 0; +} + +void ApplicationExt::Quit() +{ + elm_exit(); +} +} // namespace DPL diff --git a/modules/core/src/apply.cpp b/modules/core/src/apply.cpp new file mode 100644 index 0000000..7ba5180 --- /dev/null +++ b/modules/core/src/apply.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file apply.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of apply functionality + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/assert.cpp b/modules/core/src/assert.cpp new file mode 100644 index 0000000..5a18977 --- /dev/null +++ b/modules/core/src/assert.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file assert.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of assert + */ +#include +#include +#include +#include +#include +#include + +namespace DPL { +void AssertProc(const char *condition, + const char *file, + int line, + const char *function) +{ +#define INTERNAL_LOG(message) \ + do \ + { \ + std::ostringstream platformLog; \ + platformLog << message; \ + DPL::Log::LogSystemSingleton::Instance().Pedantic( \ + platformLog.str().c_str(), \ + __FILE__, __LINE__, __FUNCTION__); \ + } \ + while (0) + + // Try to log failed assertion to log system + Try + { + INTERNAL_LOG( + "################################################################################"); + INTERNAL_LOG( + "### DPL assertion failed! ###"); + INTERNAL_LOG( + "################################################################################"); + INTERNAL_LOG("### Condition: " << condition); + INTERNAL_LOG("### File: " << file); + INTERNAL_LOG("### Line: " << line); + INTERNAL_LOG("### Function: " << function); + INTERNAL_LOG( + "################################################################################"); + } catch (Exception) { + // Just ignore possible double errors + } + + // print assertion message to stderr + fprintf(stderr, "Assert!! [%s:%s] %s\n", file, function, condition); + + // Fail with c-library abort + abort(); +} +} // namespace DPL diff --git a/modules/core/src/atomic.cpp b/modules/core/src/atomic.cpp new file mode 100644 index 0000000..2f50074 --- /dev/null +++ b/modules/core/src/atomic.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file atomic.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of atomic + */ +#include +#include + +namespace DPL { +Atomic::Atomic(ValueType value) : + m_value(value) +{} + +Atomic::ValueType Atomic::ExchangeAndAdd(ValueType value) +{ + return g_atomic_int_add(const_cast(&m_value), value); +} + +bool Atomic::CompareAndExchange(ValueType oldValue, ValueType newValue) +{ + return g_atomic_int_compare_and_exchange(const_cast(&m_value), + oldValue, + newValue); +} + +bool Atomic::operator--() +{ + return g_atomic_int_dec_and_test(const_cast(&m_value)) != TRUE; +} + +void Atomic::operator++() +{ + g_atomic_int_inc(const_cast(&m_value)); +} + +Atomic::operator ValueType() const +{ + return g_atomic_int_get(const_cast(&m_value)); +} +} // namespace DPL diff --git a/modules/core/src/binary_queue.cpp b/modules/core/src/binary_queue.cpp new file mode 100644 index 0000000..2234c8f --- /dev/null +++ b/modules/core/src/binary_queue.cpp @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file binary_queue.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of binary queue + */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +BinaryQueue::BinaryQueue() : + m_size(0) +{} + +BinaryQueue::BinaryQueue(const BinaryQueue &other) : + m_size(0) +{ + AppendCopyFrom(other); +} + +BinaryQueue::~BinaryQueue() +{ + // Remove all remainig buckets + Clear(); +} + +const BinaryQueue &BinaryQueue::operator=(const BinaryQueue &other) +{ + if (this != &other) { + Clear(); + AppendCopyFrom(other); + } + + return *this; +} + +void BinaryQueue::AppendCopyFrom(const BinaryQueue &other) +{ + // To speed things up, always copy as one bucket + void *bufferCopy = malloc(other.m_size); + + if (bufferCopy == NULL) { + throw std::bad_alloc(); + } + + try { + other.Flatten(bufferCopy, other.m_size); + AppendUnmanaged(bufferCopy, other.m_size, &BufferDeleterFree, NULL); + } catch (const std::bad_alloc &) { + // Free allocated memory + free(bufferCopy); + throw; + } +} + +void BinaryQueue::AppendMoveFrom(BinaryQueue &other) +{ + // Copy all buckets + std::copy(other.m_buckets.begin(), + other.m_buckets.end(), std::back_inserter(m_buckets)); + m_size += other.m_size; + + // Clear other, but do not free memory + other.m_buckets.clear(); + other.m_size = 0; +} + +void BinaryQueue::AppendCopyTo(BinaryQueue &other) const +{ + other.AppendCopyFrom(*this); +} + +void BinaryQueue::AppendMoveTo(BinaryQueue &other) +{ + other.AppendMoveFrom(*this); +} + +void BinaryQueue::Clear() +{ + std::for_each(m_buckets.begin(), m_buckets.end(), &DeleteBucket); + m_buckets.clear(); + m_size = 0; +} + +void BinaryQueue::AppendCopy(const void* buffer, size_t bufferSize) +{ + // Create data copy with malloc/free + void *bufferCopy = malloc(bufferSize); + + // Check if allocation succeded + if (bufferCopy == NULL) { + throw std::bad_alloc(); + } + + // Copy user data + memcpy(bufferCopy, buffer, bufferSize); + + try { + // Try to append new bucket + AppendUnmanaged(bufferCopy, bufferSize, &BufferDeleterFree, NULL); + } catch (const std::bad_alloc &) { + // Free allocated memory + free(bufferCopy); + throw; + } +} + +void BinaryQueue::AppendUnmanaged(const void* buffer, + size_t bufferSize, + BufferDeleter deleter, + void* userParam) +{ + // Do not attach empty buckets + if (bufferSize == 0) { + deleter(buffer, bufferSize, userParam); + return; + } + + // Just add new bucket with selected deleter + m_buckets.push_back(new Bucket(buffer, bufferSize, deleter, userParam)); + + // Increase total queue size + m_size += bufferSize; +} + +size_t BinaryQueue::Size() const +{ + return m_size; +} + +bool BinaryQueue::Empty() const +{ + return m_size == 0; +} + +void BinaryQueue::Consume(size_t size) +{ + // Check parameters + if (size > m_size) { + Throw(Exception::OutOfData); + } + + size_t bytesLeft = size; + + // Consume data and/or remove buckets + while (bytesLeft > 0) { + // Get consume size + size_t count = std::min(bytesLeft, m_buckets.front()->left); + + m_buckets.front()->ptr = + static_cast(m_buckets.front()->ptr) + count; + m_buckets.front()->left -= count; + bytesLeft -= count; + m_size -= count; + + if (m_buckets.front()->left == 0) { + DeleteBucket(m_buckets.front()); + m_buckets.pop_front(); + } + } +} + +void BinaryQueue::Flatten(void *buffer, size_t bufferSize) const +{ + // Check parameters + if (bufferSize == 0) { + return; + } + + if (bufferSize > m_size) { + Throw(Exception::OutOfData); + } + + size_t bytesLeft = bufferSize; + void *ptr = buffer; + BucketList::const_iterator bucketIterator = m_buckets.begin(); + Assert(m_buckets.end() != bucketIterator); + + // Flatten data + while (bytesLeft > 0) { + // Get consume size + size_t count = std::min(bytesLeft, (*bucketIterator)->left); + + // Copy data to user pointer + memcpy(ptr, (*bucketIterator)->ptr, count); + + // Update flattened bytes count + bytesLeft -= count; + ptr = static_cast(ptr) + count; + + // Take next bucket + ++bucketIterator; + } +} + +void BinaryQueue::FlattenConsume(void *buffer, size_t bufferSize) +{ + // FIXME: Optimize + Flatten(buffer, bufferSize); + Consume(bufferSize); +} + +void BinaryQueue::DeleteBucket(BinaryQueue::Bucket *bucket) +{ + delete bucket; +} + +void BinaryQueue::BufferDeleterFree(const void* data, + size_t dataSize, + void* userParam) +{ + (void)dataSize; + (void)userParam; + + // Default free deleter + free(const_cast(data)); +} + +BinaryQueue::Bucket::Bucket(const void* data, + size_t dataSize, + BufferDeleter dataDeleter, + void* userParam) : + buffer(data), + ptr(data), + size(dataSize), + left(dataSize), + deleter(dataDeleter), + param(userParam) +{ + Assert(data != NULL); + Assert(deleter != NULL); +} + +BinaryQueue::Bucket::~Bucket() +{ + // Invoke deleter on bucket data + deleter(buffer, size, param); +} + +BinaryQueue::BucketVisitor::~BucketVisitor() +{} + +BinaryQueue::BucketVisitorCall::BucketVisitorCall(BucketVisitor *visitor) : + m_visitor(visitor) +{} + +BinaryQueue::BucketVisitorCall::~BucketVisitorCall() +{} + +void BinaryQueue::BucketVisitorCall::operator()(Bucket *bucket) const +{ + m_visitor->OnVisitBucket(bucket->ptr, bucket->left); +} + +void BinaryQueue::VisitBuckets(BucketVisitor *visitor) const +{ + Assert(visitor != NULL); + + // Visit all buckets + std::for_each(m_buckets.begin(), m_buckets.end(), BucketVisitorCall(visitor)); +} + +BinaryQueueAutoPtr BinaryQueue::Read(size_t size) +{ + // Simulate input stream + size_t available = std::min(size, m_size); + + ScopedFree bufferCopy(malloc(available)); + + if (!bufferCopy) { + throw std::bad_alloc(); + } + + BinaryQueueAutoPtr result(new BinaryQueue()); + + Flatten(bufferCopy.Get(), available); + result->AppendUnmanaged( + bufferCopy.Get(), available, &BufferDeleterFree, NULL); + bufferCopy.Release(); + Consume(available); + + return result; +} + +size_t BinaryQueue::Write(const BinaryQueue &buffer, size_t bufferSize) +{ + // Simulate output stream + AppendCopyFrom(buffer); + return bufferSize; +} +} // namespace DPL diff --git a/modules/core/src/char_traits.cpp b/modules/core/src/char_traits.cpp new file mode 100644 index 0000000..32b9197 --- /dev/null +++ b/modules/core/src/char_traits.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file char_traits.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @biref Char traits are used to create basic_string extended with + * additional features + * Current char traits could be extended in feature to boost + * performance + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/colors.cpp b/modules/core/src/colors.cpp new file mode 100644 index 0000000..0b2fcd4 --- /dev/null +++ b/modules/core/src/colors.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file colors.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Some constants with definition of colors for Console + * and html output + */ +#include +#include + +namespace DPL { +namespace Colors { +namespace Text { +const char* BOLD_GREEN_BEGIN = "\033[1;32m"; +const char* BOLD_GREEN_END = "\033[m"; +const char* RED_BEGIN = "\033[0;31m"; +const char* RED_END = "\033[m"; +const char* PURPLE_BEGIN = "\033[0;35m"; +const char* PURPLE_END = "\033[m"; +const char* GREEN_BEGIN = "\033[0;32m"; +const char* GREEN_END = "\033[m"; +const char* CYAN_BEGIN = "\033[0;36m"; +const char* CYAN_END = "\033[m"; +const char* BOLD_RED_BEGIN = "\033[1;31m"; +const char* BOLD_RED_END = "\033[m"; +const char* BOLD_YELLOW_BEGIN = "\033[1;33m"; +const char* BOLD_YELLOW_END = "\033[m"; +const char* BOLD_GOLD_BEGIN = "\033[0;33m"; +const char* BOLD_GOLD_END = "\033[m"; +const char* BOLD_WHITE_BEGIN = "\033[1;37m"; +const char* BOLD_WHITE_END = "\033[m"; +} //namespace Text + +namespace Html { +const char* BOLD_GREEN_BEGIN = ""; +const char* BOLD_GREEN_END = ""; +const char* PURPLE_BEGIN = ""; +const char* PURPLE_END = ""; +const char* RED_BEGIN = ""; +const char* RED_END = ""; +const char* GREEN_BEGIN = ""; +const char* GREEN_END = ""; +const char* CYAN_BEGIN = ""; +const char* CYAN_END = ""; +const char* BOLD_RED_BEGIN = ""; +const char* BOLD_RED_END = ""; +const char* BOLD_YELLOW_BEGIN = ""; +const char* BOLD_YELLOW_END = ""; +const char* BOLD_GOLD_BEGIN = ""; +const char* BOLD_GOLD_END = ""; +const char* BOLD_WHITE_BEGIN = ""; +const char* BOLD_WHITE_END = ""; +} //namespace Html +} //namespace Colors +} //namespace DPL diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp new file mode 100644 index 0000000..c05d06c --- /dev/null +++ b/modules/core/src/copy.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file copy.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of copy + */ +#include +#include +#include +#include + +namespace DPL { +namespace // anonymous +{ +const size_t DEFAULT_COPY_BUFFER_SIZE = 16768; +} // namespace anonymous + +void Copy(AbstractWaitableInput *input, AbstractWaitableOutput *output) +{ + Try + { + while (true) { + BinaryQueueAutoPtr buffer; + + while (true) { + // Try to get data immediately + buffer = input->Read(DEFAULT_COPY_BUFFER_SIZE); + + // Do we need to wait for data ? + if (!buffer.get()) { + WaitForSingleHandle( + input->WaitableReadHandle(), WaitMode::Read); + continue; + } + + if (buffer->Empty()) { + return; // Done + } + // Ok, to process + break; + } + + // Write out all data + while (!buffer->Empty()) { + // Try to write all data immediately + size_t count = output->Write(*buffer, buffer->Size()); + + // Do we need to wait for writing data ? + if (count == 0) { + WaitForSingleHandle( + output->WaitableWriteHandle(), WaitMode::Write); + continue; + } + + // Consume data + buffer->Consume(count); + } + } + } + Catch(DPL::Exception) + { + ReThrow(CopyFailed); + } +} + +void Copy(AbstractWaitableInput *input, + AbstractWaitableOutput *output, + size_t totalBytes) +{ + Try + { + size_t bytesLeft = totalBytes; + + while (bytesLeft > 0) { + BinaryQueueAutoPtr buffer; + + // Copy at most left bytes + size_t bytesToCopy = bytesLeft > + DEFAULT_COPY_BUFFER_SIZE ? DEFAULT_COPY_BUFFER_SIZE : bytesLeft; + + while (true) { + // Try to get data immediately + buffer = input->Read(bytesToCopy); + + // Do we need to wait for data ? + if (!buffer.get()) { + WaitForSingleHandle( + input->WaitableReadHandle(), WaitMode::Read); + continue; + } + + if (buffer->Empty()) { + ThrowMsg(CopyFailed, "Unexpected end of abstract input"); + } + + // Ok, to process + break; + } + + // Write out all data + while (!buffer->Empty()) { + // Try to write all data immediately + size_t count = output->Write(*buffer, buffer->Size()); + + // Do we need to wait for writing data ? + if (count == 0) { + WaitForSingleHandle( + output->WaitableWriteHandle(), WaitMode::Write); + continue; + } + + // Consume data + buffer->Consume(count); + bytesLeft -= count; + } + } + } + Catch(DPL::Exception) + { + ReThrow(CopyFailed); + } +} +} // namespace DPL diff --git a/modules/core/src/errno_string.cpp b/modules/core/src/errno_string.cpp new file mode 100644 index 0000000..86cb59b --- /dev/null +++ b/modules/core/src/errno_string.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file errno_string.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of errno string + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace // anonymous +{ +const size_t DEFAULT_ERRNO_STRING_SIZE = 32; +} // namespace anonymous + +std::string GetErrnoString(int error) +{ + size_t size = DEFAULT_ERRNO_STRING_SIZE; + char *buffer = NULL; + + for (;;) { + // Add one extra characted for end of string null value + char *newBuffer = static_cast(::realloc(buffer, size + 1)); + + if (!newBuffer) { + // Failed to realloc + ::free(buffer); + throw std::bad_alloc(); + } + + // Setup reallocated buffer + buffer = newBuffer; + ::memset(buffer, 0, size + 1); + + // Try to retrieve error string +#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE + // The XSI-compliant version of strerror_r() is provided if: + int result = ::strerror_r(error, buffer, size); + + if (result == 0) { + ScopedFree scopedBufferFree(buffer); + return std::string(buffer); + } +#else + errno = 0; + + // Otherwise, the GNU-specific version is provided. + char *result = ::strerror_r(error, buffer, size); + + if (result != NULL) { + ScopedFree scopedBufferFree(buffer); + return std::string(result); + } +#endif + + // Interpret errors + switch (errno) { + case EINVAL: + // We got an invalid errno value + ::free(buffer); + ThrowMsg(InvalidErrnoValue, "Invalid errno value: " << error); + + case ERANGE: + // Incease buffer size and retry + size <<= 1; + continue; + + default: + AssertMsg(0, "Invalid errno value after call to strerror_r!"); + } + } +} +} // namespace DPL diff --git a/modules/core/src/exception.cpp b/modules/core/src/exception.cpp new file mode 100644 index 0000000..d3673e6 --- /dev/null +++ b/modules/core/src/exception.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file exception.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation of exception system + */ +#include +#include +#include +#include + +namespace DPL { +Exception* Exception::m_lastException = NULL; +unsigned int Exception::m_exceptionCount = 0; +void (*Exception::m_terminateHandler)() = NULL; + +void LogUnhandledException(const std::string &str) +{ + // Logging to console + printf("%s\n", str.c_str()); + + // Logging to dlog + LogPedantic(str); +} + +void LogUnhandledException(const std::string &str, + const char *filename, + int line, + const char *function) +{ + // Logging to console + std::ostringstream msg; + msg << "\033[1;5;31m\n=== [" << filename << ":" << line << "] " << + function << " ===\033[m"; + msg << str; + printf("%s\n", msg.str().c_str()); + + // Logging to dlog + DPL::Log::LogSystemSingleton::Instance().Error( + str.c_str(), filename, line, function); +} +} // namespace DPL diff --git a/modules/core/src/file_input.cpp b/modules/core/src/file_input.cpp new file mode 100644 index 0000000..36fb4b5 --- /dev/null +++ b/modules/core/src/file_input.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file file_input.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named input pipe + */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace // anonymous +{ +const size_t DEFAULT_READ_BUFFER_SIZE = 4096; +} // namespace anonymous + +FileInput::FileInput() : + m_fd(-1) +{} + +FileInput::FileInput(const std::string& fileName) : + m_fd(-1) +{ + Open(fileName); +} + +FileInput::~FileInput() +{ + Close(); +} + +void FileInput::Open(const std::string& fileName) +{ + // Open non-blocking + int fd = TEMP_FAILURE_RETRY(open(fileName.c_str(), O_RDONLY | O_NONBLOCK)); + + // Throw an exception if an error occurred + if (fd == -1) { + ThrowMsg(Exception::OpenFailed, fileName); + } + + // Close if any existing + Close(); + + // Save new descriptor + m_fd = fd; + + LogPedantic("Opened file: " << fileName); +} + +void FileInput::Close() +{ + if (m_fd == -1) { + return; + } + + if (TEMP_FAILURE_RETRY(close(m_fd)) == -1) { + Throw(Exception::CloseFailed); + } + + m_fd = -1; + + LogPedantic("Closed file"); +} + +BinaryQueueAutoPtr FileInput::Read(size_t size) +{ + size_t bytesToRead = size > + DEFAULT_READ_BUFFER_SIZE ? DEFAULT_READ_BUFFER_SIZE : size; + + // Malloc default read buffer size + // It is unmanaged, so it can be then attached directly to binary queue + void *buffer = malloc(bytesToRead); + + if (buffer == NULL) { + throw std::bad_alloc(); + } + + LogPedantic("Trying to read " << bytesToRead << " bytes"); + + ssize_t result = TEMP_FAILURE_RETRY(read(m_fd, buffer, bytesToRead)); + + LogPedantic("Read " << result << " bytes from file"); + + if (result > 0) { + // Succedded to read socket data + BinaryQueueAutoPtr binaryQueue(new BinaryQueue()); + + // Append unmanaged memory + binaryQueue->AppendUnmanaged(buffer, + result, + &BinaryQueue::BufferDeleterFree, + NULL); + + // Return buffer + return binaryQueue; + } else if (result == 0) { + // Socket was gracefuly closed + free(buffer); + + // Return empty buffer + return BinaryQueueAutoPtr(new BinaryQueue()); + } else { + // Must first save errno value, because it may be altered + int lastErrno = errno; + + // Free buffer + free(buffer); + + // Interpret error result + (void)lastErrno; + + // FIXME: Handle specific errno + Throw(AbstractInput::Exception::ReadFailed); + } +} + +WaitableHandle FileInput::WaitableReadHandle() const +{ + return static_cast(m_fd); +} +} // namespace DPL diff --git a/modules/core/src/file_output.cpp b/modules/core/src/file_output.cpp new file mode 100644 index 0000000..8342698 --- /dev/null +++ b/modules/core/src/file_output.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file file_output.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of file output + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +FileOutput::FileOutput() : + m_fd(-1) +{} + +FileOutput::FileOutput(const std::string& fileName) : + m_fd(-1) +{ + Open(fileName); +} + +FileOutput::~FileOutput() +{ + Close(); +} + +void FileOutput::Open(const std::string& fileName) +{ + // Open non-blocking + int fd = + TEMP_FAILURE_RETRY(open(fileName.c_str(), O_WRONLY | O_CREAT | + O_TRUNC | + O_NONBLOCK, 0664)); + + // Throw an exception if an error occurred + if (fd == -1) { + ThrowMsg(Exception::OpenFailed, fileName); + } + + // Close if any existing + Close(); + + // Save new descriptor + m_fd = fd; + + LogPedantic("Opened file: " << fileName); +} + +void FileOutput::Close() +{ + if (m_fd == -1) { + return; + } + + if (TEMP_FAILURE_RETRY(close(m_fd)) == -1) { + Throw(Exception::CloseFailed); + } + + m_fd = -1; + + LogPedantic("Closed file"); +} + +size_t FileOutput::Write(const BinaryQueue &buffer, size_t bufferSize) +{ + // Adjust write size + if (bufferSize > buffer.Size()) { + bufferSize = buffer.Size(); + } + + // FIXME: User write visitor to write ! + // WriteVisitor visitor + + ScopedFree flattened(malloc(bufferSize)); + buffer.Flatten(flattened.Get(), bufferSize); + + LogPedantic("Trying to write " << bufferSize << " bytes"); + + ssize_t result = TEMP_FAILURE_RETRY(write(m_fd, flattened.Get(), bufferSize)); + + LogPedantic("Wrote " << result << " bytes to file"); + + if (result > 0) { + // Successfuly written some bytes + return static_cast(result); + } else if (result == 0) { + // This is abnormal result + ThrowMsg(CommonException::InternalError, + "Invalid write result, 0 bytes written"); + } else { + // Interpret error result + // FIXME: Handle errno + Throw(AbstractOutput::Exception::WriteFailed); + } +} + +WaitableHandle FileOutput::WaitableWriteHandle() const +{ + return static_cast(m_fd); +} +} // namespace DPL diff --git a/modules/core/src/generic_event.cpp b/modules/core/src/generic_event.cpp new file mode 100644 index 0000000..f09ff2b --- /dev/null +++ b/modules/core/src/generic_event.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_event.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC generic event + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/lexical_cast.cpp b/modules/core/src/lexical_cast.cpp new file mode 100644 index 0000000..a89abc9 --- /dev/null +++ b/modules/core/src/lexical_cast.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file lexical_cast.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for lexical cast + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/main.cpp b/modules/core/src/main.cpp new file mode 100644 index 0000000..1d0326b --- /dev/null +++ b/modules/core/src/main.cpp @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main for EFL + */ +#include +#include +#include +#include +#include +#include +#include +#include + +IMPLEMENT_SINGLETON(DPL::Main) + +namespace DPL { +namespace // anonymous +{ +// Late EFL event handling +Main *g_lateMain = NULL; +} // namespace anonymous + +Main::Main() +#ifdef DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND +// GLIB loop intergration workaround + : m_oldEcoreSelect(NULL) +#endif // DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND +{ + // Late EFL event handling + Assert(g_lateMain == NULL); + g_lateMain = this; + + // Increment ECORE init count to ensure we have all + // subsystems correctly set-up until main dispatcher dtor + // This is especially important when MainEventDispatcher + // is a global object destroyed no earlier than crt destroy routine + ecore_init(); + +#ifdef DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND + // GLIB loop intergration workaround + union ConvertPointer + { + Ecore_Select_Function pointer; + EcoreSelectType function; + } convert; + + convert.pointer = ecore_main_loop_select_func_get(); + m_oldEcoreSelect = convert.function; + + ecore_main_loop_select_func_set(&EcoreSelectInterceptor); +#endif // DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND + + // Register event invoker + m_invokerHandler = ecore_main_fd_handler_add( + WaitableHandleWatchSupport::WaitableInvokerHandle(), + ECORE_FD_READ, + &StaticDispatchInvoker, + this, + NULL, + NULL); + + if (m_invokerHandler == NULL) { + ThrowMsg(Exception::CreateFailed, "Failed to register invoker handler!"); + } + + // It is impossible that there exist watchers at this time + // No need to add watchers + LogPedantic("ECORE event handler registered"); +} + +Main::~Main() +{ + // Remove any watchers + for (EcoreFdHandlerList::iterator iterator = m_readWatchersList.begin(); + iterator != m_readWatchersList.end(); + ++iterator) + { + ecore_main_fd_handler_del(*iterator); + } + + m_readWatchersList.clear(); + + for (EcoreFdHandlerList::iterator iterator = m_writeWatchersList.begin(); + iterator != m_writeWatchersList.end(); + ++iterator) + { + ecore_main_fd_handler_del(*iterator); + } + + m_writeWatchersList.clear(); + + // Remove event invoker + ecore_main_fd_handler_del(m_invokerHandler); + m_invokerHandler = NULL; + + //set old ecore select function, because after ecore_shutdown() call, + //it is being called once again and it may crash. + ecore_main_loop_select_func_set(m_oldEcoreSelect); + // Decrement ECORE init count + // We do not need ecore routines any more + ecore_shutdown(); + + // Late EFL event handling + Assert(g_lateMain == this); + g_lateMain = NULL; +} + +Eina_Bool Main::StaticDispatchInvoker(void *data, Ecore_Fd_Handler *fd_handler) +{ + LogPedantic("Static ECORE dispatch invoker"); + + Main *This = static_cast
(data); + (void)fd_handler; + + Assert(This != NULL); + + // Late EFL event handling + if (g_lateMain == NULL) { + LogPedantic("WARNING: Late EFL invoker dispatch!"); + } else { + This->DispatchInvoker(); + } + + return ECORE_CALLBACK_RENEW; +} + +Eina_Bool Main::StaticDispatchReadWatcher(void* data, + Ecore_Fd_Handler* fd_handler) +{ + LogPedantic("Static ECORE dispatch read watcher"); + + Main *This = static_cast
(data); + + Assert(This != NULL); + + // Late EFL event handling + if (g_lateMain == NULL) { + LogPedantic("WARNING: Late EFL read watcher dispatch!"); + } else { + This->DispatchReadWatcher(static_cast( + ecore_main_fd_handler_fd_get(fd_handler))); + } + + return ECORE_CALLBACK_RENEW; +} + +Eina_Bool Main::StaticDispatchWriteWatcher(void* data, + Ecore_Fd_Handler* fd_handler) +{ + LogPedantic("Static ECORE dispatch write watcher"); + + Main *This = static_cast
(data); + + Assert(This != NULL); + + // Late EFL event handling + if (g_lateMain == NULL) { + LogPedantic("WARNING: Late EFL write watcher dispatch!"); + } else { + This->DispatchWriteWatcher(static_cast( + ecore_main_fd_handler_fd_get(fd_handler))); + } + + return ECORE_CALLBACK_RENEW; +} + +void Main::DispatchInvoker() +{ + LogPedantic("Dispatching invoker..."); + + // Reload watch list + ReloadWatchList(); + + // Handle base invoker + WaitableHandleWatchSupport::InvokerFinished(); + + LogPedantic("Invoker dispatched"); +} + +void Main::ReloadWatchList() +{ + LogPedantic( + "Reloading watch list... (" << m_readWatchersList.size() << " + " << + m_writeWatchersList.size() << ")"); + + // Reload list of watchers + WaitableHandleListEx waitableWatcherHandles = + WaitableHandleWatchSupport::WaitableWatcherHandles(); + + // Remove not existing read watchers + EcoreFdHandlerList::iterator watchersIterator = m_readWatchersList.begin(); + WaitableHandleListEx::iterator handlesIterator; + + while (watchersIterator != m_readWatchersList.end()) { + bool found = false; + + for (handlesIterator = waitableWatcherHandles.begin(); + handlesIterator != waitableWatcherHandles.end(); + ++handlesIterator) + { + if (handlesIterator->second == WaitMode::Read && + handlesIterator->first == + static_cast(ecore_main_fd_handler_fd_get(* + watchersIterator))) + { + found = true; + break; + } + } + + if (!found) { + // Unregister handler + ecore_main_fd_handler_del(*watchersIterator); + + // Remove iterator + EcoreFdHandlerList::iterator next = watchersIterator; + ++next; + + m_readWatchersList.erase(watchersIterator); + watchersIterator = next; + } else { + ++watchersIterator; + } + } + + // Remove not existing write watchers + watchersIterator = m_writeWatchersList.begin(); + + while (watchersIterator != m_writeWatchersList.end()) { + bool found = false; + + for (handlesIterator = waitableWatcherHandles.begin(); + handlesIterator != waitableWatcherHandles.end(); + ++handlesIterator) + { + if (handlesIterator->second == WaitMode::Write && + handlesIterator->first == + static_cast(ecore_main_fd_handler_fd_get(* + watchersIterator))) + { + found = true; + break; + } + } + + if (!found) { + // Unregister handler + ecore_main_fd_handler_del(*watchersIterator); + + // Remove iterator + EcoreFdHandlerList::iterator next = watchersIterator; + ++next; + + m_writeWatchersList.erase(watchersIterator); + watchersIterator = next; + } else { + ++watchersIterator; + } + } + + // Add new read/write watchers + for (handlesIterator = waitableWatcherHandles.begin(); + handlesIterator != waitableWatcherHandles.end(); + ++handlesIterator) + { + if (handlesIterator->second == WaitMode::Read) { + bool found = false; + + for (watchersIterator = m_readWatchersList.begin(); + watchersIterator != m_readWatchersList.end(); + ++watchersIterator) + { + if (handlesIterator->first == + static_cast(ecore_main_fd_handler_fd_get(* + watchersIterator))) + { + found = true; + break; + } + } + + if (!found) { + Ecore_Fd_Handler *handler = ecore_main_fd_handler_add( + handlesIterator->first, + ECORE_FD_READ, + &StaticDispatchReadWatcher, + this, + NULL, + NULL); + if (handler == NULL) { + ThrowMsg(Exception::CreateFailed, + "Failed to register read watcher handler!"); + } + + // Push new watcher to list + m_readWatchersList.push_back(handler); + } + } else if (handlesIterator->second == WaitMode::Write) { + bool found = false; + + for (watchersIterator = m_writeWatchersList.begin(); + watchersIterator != m_writeWatchersList.end(); + ++watchersIterator) + { + if (handlesIterator->first == + static_cast(ecore_main_fd_handler_fd_get(* + watchersIterator))) + { + found = true; + break; + } + } + + if (!found) { + Ecore_Fd_Handler *handler = ecore_main_fd_handler_add( + handlesIterator->first, + ECORE_FD_WRITE, + &StaticDispatchWriteWatcher, + this, + NULL, + NULL); + if (handler == NULL) { + ThrowMsg(Exception::CreateFailed, + "Failed to register write watcher handler!"); + } + + // Push new watcher to list + m_writeWatchersList.push_back(handler); + } + } else { + Assert(0); + } + } + + LogPedantic( + "Watch list reloaded (" << m_readWatchersList.size() << " + " << + m_writeWatchersList.size() << ")"); +} + +void Main::DispatchReadWatcher(WaitableHandle waitableHandle) +{ + LogPedantic("Dispatching read watcher..."); + + // Handle watcher + WaitableHandleWatchSupport::HandleWatcher(waitableHandle, WaitMode::Read); + + LogPedantic("Watcher dispatched"); +} + +void Main::DispatchWriteWatcher(WaitableHandle waitableHandle) +{ + LogPedantic("Dispatching write watcher..."); + + // Handle watcher + WaitableHandleWatchSupport::HandleWatcher(waitableHandle, WaitMode::Write); + + LogPedantic("Watcher dispatched"); +} + +Thread *Main::GetInvokerThread() +{ + return NULL; +} + +void Main::HandleDirectInvoker() +{ + // Handle direct invoker + ReloadWatchList(); +} + +#ifdef DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND +// GLIB loop intergration workaround +int Main::EcoreSelectInterceptor(int nfds, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout) +{ + // We have to check error code here and make another try because of some + // glib error's. + fd_set rfds, wfds, efds; + memcpy(&rfds, readfds, sizeof(fd_set)); + memcpy(&wfds, writefds, sizeof(fd_set)); + memcpy(&efds, exceptfds, sizeof(fd_set)); + + int ret = MainSingleton::Instance().m_oldEcoreSelect(nfds, + readfds, + writefds, + exceptfds, + timeout); + + if (ret == -1) { + // Check each descriptor to see if it is valid + for (int i = 0; i < nfds; i++) { + if (FD_ISSET(i, + readfds) || + FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds)) + { + // Try to get descriptor flags + int result = fcntl(i, F_GETFL); + + if (result == -1) { + if (errno == EBADF) { + // This a bad descriptor. Remove all occurrences of it. + if (FD_ISSET(i, readfds)) { + LogPedantic( + "GLIB_LOOP_INTEGRATION_WORKAROUND: Bad read descriptor: " + << i); + FD_CLR(i, readfds); + } + + if (FD_ISSET(i, writefds)) { + LogPedantic( + "GLIB_LOOP_INTEGRATION_WORKAROUND: Bad write descriptor: " + << i); + FD_CLR(i, writefds); + } + + if (FD_ISSET(i, exceptfds)) { + LogPedantic( + "GLIB_LOOP_INTEGRATION_WORKAROUND: Bad exception descriptor: " + << i); + FD_CLR(i, exceptfds); + } + } else { + // Unexpected error + Assert(0); + } + } + } + } + + LogPedantic( + "GLIB_LOOP_INTEGRATION_WORKAROUND: Bad read descriptor. Retrying with default select."); + + //Retry with old values and return new error + memcpy(readfds, &rfds, sizeof(fd_set)); + memcpy(writefds, &wfds, sizeof(fd_set)); + memcpy(exceptfds, &efds, sizeof(fd_set)); + + // Trying to do it very short + timeval tm; + tm.tv_sec = 0; + tm.tv_usec = 10; + + if (timeout) { + ret = select(nfds, readfds, writefds, exceptfds, &tm); + } else { + ret = select(nfds, readfds, writefds, exceptfds, NULL); + } + } + + return ret; +} +#endif // DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND +} // namespace DPL diff --git a/modules/core/src/mutable_task_list.cpp b/modules/core/src/mutable_task_list.cpp new file mode 100644 index 0000000..f8886fa --- /dev/null +++ b/modules/core/src/mutable_task_list.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file task_list.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + * @brief Implementation file for task list + */ +#include +#include +#include + +namespace DPL { +MutableTaskList::MutableTaskList() : + m_running(false) +{ + m_currentTask = m_tasks.end(); +} + +MutableTaskList::~MutableTaskList() +{ + for (Tasks::iterator i = m_tasks.begin(); i != m_tasks.end(); ++i) { + delete *i; + } +} + +void MutableTaskList::AddTask(Task *task) +{ + if(m_tasks.empty()) + { + m_tasks.push_back(task); + m_currentTask = m_tasks.begin(); + } + else + { + m_tasks.push_back(task); + } +} + +bool MutableTaskList::NextStep() +{ + m_running = true; + + AssertMsg( + m_currentTask != m_tasks.end(), + "Task list is empty or all tasks done"); + + bool result = (*m_currentTask)->NextStep(); + + if (result) { + return true; + } + + return ++m_currentTask != m_tasks.end(); +} + +bool MutableTaskList::Abort() +{ + m_tasks.erase(m_currentTask, m_tasks.end()); + m_tasks.reverse(); + for (Tasks::iterator i = m_tasks.begin(); i != m_tasks.end();) { + //If given task does not have any "abortSteps", remove it from the list + if (!(*i)->Abort()) { + delete *i; + i = m_tasks.erase(i); + continue; + } + ++i; + } + + if (m_tasks.empty()) { + return false; + } + + m_currentTask = m_tasks.begin(); + + return true; +} + +size_t MutableTaskList::GetStepCount() const +{ + size_t count = 0; + + for (Tasks::const_iterator i = m_tasks.begin(); i != m_tasks.end(); ++i) { + count += (*i)->GetStepCount(); + } + + return count; +} + +} // namespace DPL diff --git a/modules/core/src/mutex.cpp b/modules/core/src/mutex.cpp new file mode 100644 index 0000000..eed1f2e --- /dev/null +++ b/modules/core/src/mutex.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file mutex.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of mutex + */ +#include +#include +#include +#include +#include + +namespace DPL { +Mutex::Mutex() +{ + if (pthread_mutex_init(&m_mutex, NULL) != 0) { + int error = errno; + + LogPedantic("Failed to create mutex. Errno: " << error); + + ThrowMsg(Exception::CreateFailed, + "Failed to create mutex. Errno: " << error); + } +} + +Mutex::~Mutex() +{ + if (pthread_mutex_destroy(&m_mutex) != 0) { + int error = errno; + + LogPedantic("Failed to destroy mutex. Errno: " << error); + } +} + +void Mutex::Lock() const +{ + if (pthread_mutex_lock(&m_mutex) != 0) { + int error = errno; + + LogPedantic("Failed to lock mutex. Errno: " << error); + + ThrowMsg(Exception::LockFailed, + "Failed to lock mutex. Errno: " << error); + } +} + +void Mutex::Unlock() const +{ + if (pthread_mutex_unlock(&m_mutex) != 0) { + int error = errno; + + LogPedantic("Failed to unlock mutex. Errno: " << error); + + ThrowMsg(Exception::UnlockFailed, + "Failed to unlock mutex. Errno: " << error); + } +} + +Mutex::ScopedLock::ScopedLock(Mutex *mutex) : + m_mutex(mutex) +{ + Assert(mutex != NULL); + m_mutex->Lock(); +} + +Mutex::ScopedLock::~ScopedLock() +{ + Try + { + m_mutex->Unlock(); + } + Catch(Mutex::Exception::UnlockFailed) + { + LogPedantic("Failed to leave mutex scoped lock"); + } +} +} // namespace DPL diff --git a/modules/core/src/named_base_pipe.cpp b/modules/core/src/named_base_pipe.cpp new file mode 100644 index 0000000..9f91d30 --- /dev/null +++ b/modules/core/src/named_base_pipe.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file named_base_pipe.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named base pipe + */ +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace // anonymous +{ +const mode_t FIFO_MODE = 0600; +} // namespace anonymous + +NamedBasePipe::~NamedBasePipe() +{} + +void NamedBasePipe::Create(const std::string &pipeName) +{ + // Create new fifo + int status = mkfifo(pipeName.c_str(), FIFO_MODE); + + if (status == -1) { + // Ignore error it it already exists + if (errno == EEXIST) { + ThrowMsg(Exception::AlreadyExist, pipeName); + } else { + ThrowMsg(Exception::CreateFailed, pipeName); + } + } +} + +void NamedBasePipe::Destroy(const std::string &fileName) +{ + // Destroy fifo + unlink(fileName.c_str()); // FIXME: Add error handling +} +} // namespace DPL diff --git a/modules/core/src/named_output_pipe.cpp b/modules/core/src/named_output_pipe.cpp new file mode 100644 index 0000000..2a9a1fa --- /dev/null +++ b/modules/core/src/named_output_pipe.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file named_output_pipe.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of named output pipe + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +NamedOutputPipe::NamedOutputPipe() : + m_fifo(-1) +{} + +NamedOutputPipe::~NamedOutputPipe() +{ + Close(); +} + +void NamedOutputPipe::Open(const std::string& pipeName) +{ + // Then open it for reading or writing + int fifo = TEMP_FAILURE_RETRY(open(pipeName.c_str(), O_WRONLY | O_NONBLOCK)); + + if (fifo == -1) { + ThrowMsg(Exception::OpenFailed, pipeName); + } + + m_fifo = fifo; +} + +void NamedOutputPipe::Close() +{ + if (m_fifo == -1) { + return; + } + + if (TEMP_FAILURE_RETRY(close(m_fifo)) == -1) { + Throw(Exception::CloseFailed); + } + + m_fifo = -1; +} + +size_t NamedOutputPipe::Write(const BinaryQueue &buffer, size_t bufferSize) +{ + // Adjust write size + if (bufferSize > buffer.Size()) { + bufferSize = buffer.Size(); + } + + // FIXME: User write visitor to write ! + // WriteVisitor visitor + + ScopedFree flattened(malloc(bufferSize)); + buffer.Flatten(flattened.Get(), bufferSize); + + ssize_t result = + TEMP_FAILURE_RETRY(write(m_fifo, flattened.Get(), bufferSize)); + + if (result > 0) { + // Successfuly written some bytes + return static_cast(result); + } else if (result == 0) { + // This is abnormal result + ThrowMsg(CommonException::InternalError, + "Invalid socket write result, 0 bytes written"); + } else { + // Interpret error result + // FIXME: Handle errno + Throw(AbstractOutput::Exception::WriteFailed); + } +} + +int NamedOutputPipe::WaitableWriteHandle() const +{ + return m_fifo; +} +} // namespace DPL diff --git a/modules/core/src/noncopyable.cpp b/modules/core/src/noncopyable.cpp new file mode 100644 index 0000000..9453655 --- /dev/null +++ b/modules/core/src/noncopyable.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file noncopyable.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of noncopyable + */ +#include +#include + +namespace DPL { +Noncopyable::Noncopyable() +{} + +Noncopyable::~Noncopyable() +{} +} // namespace DPL diff --git a/modules/core/src/once.cpp b/modules/core/src/once.cpp new file mode 100644 index 0000000..f2d4a1a --- /dev/null +++ b/modules/core/src/once.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file once.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of once + */ +#include +#include + +namespace DPL { +void Once::Call(Delegate delegate) +{ + // First chance test + if (m_atomic == 1) { + return; + } + + // Enter mutex + Mutex::ScopedLock lock(&m_mutex); + + // Second chance test + if (m_atomic == 1) { + return; + } + + // Initialization: call delegate + delegate(); + + // Initialization: done + ++m_atomic; +} +} // namespace DPL diff --git a/modules/core/src/read_write_mutex.cpp b/modules/core/src/read_write_mutex.cpp new file mode 100644 index 0000000..ef34758 --- /dev/null +++ b/modules/core/src/read_write_mutex.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file read_write_mutex.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of read write mutex + */ +#include +#include +#include + +namespace DPL { +ReadWriteMutex::ReadWriteMutex() +{ + if (pthread_rwlock_init(&m_rwlock, NULL) != 0) { + Throw(Exception::CreateFailed); + } +} + +ReadWriteMutex::~ReadWriteMutex() +{ + if (pthread_rwlock_destroy(&m_rwlock) != 0) { + Throw(Exception::DestroyFailed); + } +} + +void ReadWriteMutex::ReadLock() const +{ + if (pthread_rwlock_rdlock(&m_rwlock) != 0) { + Throw(Exception::ReadLockFailed); + } +} + +void ReadWriteMutex::WriteLock() const +{ + if (pthread_rwlock_wrlock(&m_rwlock) != 0) { + Throw(Exception::WriteLockFailed); + } +} + +void ReadWriteMutex::Unlock() const +{ + if (pthread_rwlock_unlock(&m_rwlock) != 0) { + Throw(Exception::UnlockFailed); + } +} + +ReadWriteMutex::ScopedReadLock::ScopedReadLock(ReadWriteMutex *mutex) : + m_mutex(mutex) +{ + Assert(mutex != NULL); + m_mutex->ReadLock(); +} + +ReadWriteMutex::ScopedReadLock::~ScopedReadLock() +{ + m_mutex->Unlock(); +} + +ReadWriteMutex::ScopedWriteLock::ScopedWriteLock(ReadWriteMutex *mutex) : + m_mutex(mutex) +{ + Assert(mutex != NULL); + m_mutex->WriteLock(); +} + +ReadWriteMutex::ScopedWriteLock::~ScopedWriteLock() +{ + m_mutex->Unlock(); +} +} // namespace DPL diff --git a/modules/core/src/recursive_mutex.cpp b/modules/core/src/recursive_mutex.cpp new file mode 100644 index 0000000..234d25f --- /dev/null +++ b/modules/core/src/recursive_mutex.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file recursive_mutex.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of recursive mutex + */ +#include +#include +#include + +namespace DPL { +RecursiveMutex::RecursiveMutex() +{ + pthread_mutexattr_t attr; + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + + if (pthread_mutex_init(&m_mutex, &attr) != 0) { + Throw(Exception::CreateFailed); + } +} + +RecursiveMutex::~RecursiveMutex() +{ + if (pthread_mutex_destroy(&m_mutex) != 0) { + Throw(Exception::DestroyFailed); + } +} + +void RecursiveMutex::Lock() const +{ + if (pthread_mutex_lock(&m_mutex) != 0) { + Throw(Exception::LockFailed); + } +} + +void RecursiveMutex::Unlock() const +{ + if (pthread_mutex_unlock(&m_mutex) != 0) { + Throw(Exception::UnlockFailed); + } +} + +RecursiveMutex::ScopedLock::ScopedLock(RecursiveMutex *mutex) : + m_mutex(mutex) +{ + Assert(mutex != NULL); + m_mutex->Lock(); +} + +RecursiveMutex::ScopedLock::~ScopedLock() +{ + m_mutex->Unlock(); +} +} // namespace DPL diff --git a/modules/core/src/scoped_dir.cpp b/modules/core/src/scoped_dir.cpp new file mode 100644 index 0000000..96550e6 --- /dev/null +++ b/modules/core/src/scoped_dir.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file scoped_dir.cpp + * @author Iwanek Tomasz (t.iwanek@samsung.com) + * @version 1.0 + * @brief This file is the implementation scoped directory + */ +#include +#include +#include + +#include +#include +#include + +namespace { + +bool removeRecusive(const char * path) +{ + FTS *fts; + FTSENT *ftsent; + bool rv = true; + char * const paths[] = { const_cast(path), NULL }; + if ((fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) == NULL) { + return false; + } + while ((ftsent = fts_read(fts)) != NULL) { + switch (ftsent->fts_info) { + case FTS_D: + break; + case FTS_DP: + if (rmdir(ftsent->fts_accpath) != 0) { + rv = false; + } + break; + case FTS_DC: + case FTS_F: + case FTS_NSOK: + case FTS_SL: + case FTS_SLNONE: + case FTS_DEFAULT: + if (unlink(ftsent->fts_accpath) != 0) { + rv = false; + } + break; + case FTS_NS: + rv = false; + break; + case FTS_DOT: + case FTS_DNR: + case FTS_ERR: + default: + rv = false; + break; + } + } + if (fts_close(fts) == -1) { + rv = false; + } + return rv; +} + +} + +namespace DPL { + +ScopedDirPolicy::Type ScopedDirPolicy::NullValue() +{ + return std::string(); +} + +void ScopedDirPolicy::Destroy(Type str) +{ + if(!str.empty()) + { + bool status = removeRecusive(str.c_str()); + if(!status) + { + LogError("Error while removing recursively: " << str); + } + } +} + +ScopedDir::ScopedDir(const std::string & str, mode_t mode) : BaseType(str) +{ + if(!str.empty()) + { + if (mkdir(str.c_str(), mode) == -1) + { + std::string errstr = DPL::GetErrnoString(); + LogError("Error while creating directory: " << str + << " [" << errstr << "]"); + } + } +} + +} // namespace DPL + diff --git a/modules/core/src/semaphore.cpp b/modules/core/src/semaphore.cpp new file mode 100644 index 0000000..387c009 --- /dev/null +++ b/modules/core/src/semaphore.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file semaphore.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of semaphore + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +void Semaphore::Remove(const std::string &fileName) +{ + if (sem_unlink(fileName.c_str()) == -1) { + int error = errno; + LogPedantic("Failed to unlink semaphore. Errno: " << error); + ThrowMsg(Exception::RemoveFailed, + "Failed to unlink semaphore. Errno: " << error); + } +} + +Semaphore::Semaphore(size_t maxLockCount) +{ + LogPedantic("Allocating unnamed semaphore:"); + LogPedantic(" Maximum lock count: " << maxLockCount); + + if (-1 == sem_init(&m_semaphore.unnamed.handle, + 0, + static_cast(maxLockCount))) + { + int error = errno; + + LogPedantic("Failed to create semaphore. Errno: " << error); + + ThrowMsg(Exception::CreateFailed, + "Failed to create semaphore. Errno: " << error); + } + + m_type = Type_Unnamed; +} + +Semaphore::Semaphore(const std::string &fileName, + bool allowCreate, + bool exclusiveCreate, + size_t maxLockCount, + int permissions, + bool unlinkOnDestroy) +{ + LogPedantic("Allocating named semaphore:"); + LogPedantic(" File name: " << fileName); + LogPedantic(" Maximum lock count: " << maxLockCount); + LogPedantic(" File name: " << fileName); + LogPedantic(" Allowed create: " << allowCreate); + LogPedantic(" Exclusive create: " << exclusiveCreate); + LogPedantic(" Permissions: " << permissions); + LogPedantic(" Unlink on destroy: " << unlinkOnDestroy); + + sem_t *semaphore; + + do { + if (allowCreate) { + if (exclusiveCreate) { + semaphore = sem_open(fileName.c_str(), + O_CREAT | O_EXCL, + permissions, + static_cast(maxLockCount)); + } else { + semaphore = sem_open(fileName.c_str(), + O_CREAT, + permissions, + static_cast(maxLockCount)); + } + } else { + semaphore = sem_open(fileName.c_str(), 0); + } + } while (semaphore == SEM_FAILED && errno == EINTR); + + if (semaphore == SEM_FAILED) { + int error = errno; + + LogPedantic("Failed to create semaphore '" << fileName + << "'. Errno: " << error); + + ThrowMsg(Exception::CreateFailed, + "Failed to create semaphore '" << fileName + << "'. Errno: " << error); + } + + m_semaphore.named.handle = semaphore; + + m_semaphore.named.name = strdup(fileName.c_str()); // May be NULL + + if (m_semaphore.named.name == NULL) { + LogPedantic("Out of memory while duplicating semaphore name"); + } + + m_semaphore.named.unlinkOnDestroy = unlinkOnDestroy; + + m_type = Type_Named; +} + +Semaphore::~Semaphore() +{ + InternalDestroy(); +} + +sem_t *Semaphore::InternalGet() const +{ + switch (m_type) { + case Type_Unnamed: + return &m_semaphore.unnamed.handle; + + case Type_Named: + return m_semaphore.named.handle; + + default: + Assert(false && "Invalid type"); + } + + return NULL; +} + +void Semaphore::InternalDestroy() +{ + switch (m_type) { + case Type_Unnamed: + if (sem_destroy(&m_semaphore.unnamed.handle) == -1) { + int error = errno; + + LogPedantic("Failed to destroy semaphore. Errno: " << error); + } + break; + + case Type_Named: + if (sem_close(m_semaphore.named.handle) == -1) { + int error = errno; + + LogPedantic("Failed to close semaphore. Errno: " << error); + } + + if (m_semaphore.named.name != NULL) { + // Unlink named semaphore + if (m_semaphore.named.unlinkOnDestroy && + sem_unlink(m_semaphore.named.name) == -1) + { + int error = errno; + + LogPedantic("Failed to unlink semaphore. Errno: " + << error); + } + + // Free name + free(m_semaphore.named.name); + } + break; + + default: + Assert(false && "Invalid type"); + } +} + +void Semaphore::Lock() const +{ + if (TEMP_FAILURE_RETRY(sem_wait(InternalGet())) != 0) { + int error = errno; + + LogPedantic("Failed to lock semaphore. Errno: " << error); + + ThrowMsg(Exception::LockFailed, + "Failed to lock semaphore. Errno: " << error); + } +} + +void Semaphore::Unlock() const +{ + if (sem_post(InternalGet()) != 0) { + int error = errno; + + LogPedantic("Failed to unlock semaphore. Errno: " << error); + + ThrowMsg(Exception::UnlockFailed, + "Failed to unlock semaphore. Errno: " << error); + } +} + +Semaphore::ScopedLock::ScopedLock(Semaphore *semaphore) : + m_semaphore(semaphore) +{ + Assert(semaphore != NULL); + m_semaphore->Lock(); +} + +Semaphore::ScopedLock::~ScopedLock() +{ + Try + { + m_semaphore->Unlock(); + } + Catch(Semaphore::Exception::UnlockFailed) + { + LogPedantic("Failed to leave semaphore scoped lock"); + } +} +} // namespace DPL diff --git a/modules/core/src/serialization.cpp b/modules/core/src/serialization.cpp new file mode 100644 index 0000000..f8f05ff --- /dev/null +++ b/modules/core/src/serialization.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file serialization.cpp + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of data serialization. + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/single_instance.cpp b/modules/core/src/single_instance.cpp new file mode 100644 index 0000000..274b5f8 --- /dev/null +++ b/modules/core/src/single_instance.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file single_instance.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of single instance + */ +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace // anonumous +{ +const char *LOCK_PREFIX_PATH = "/tmp/dpl_single_instance_"; +} +SingleInstance::SingleInstance() : + m_locked(false), + m_fdLock(-1) +{} + +SingleInstance::~SingleInstance() +{ + AssertMsg(!m_locked, "Single instance must be released before exit!"); +} + +bool SingleInstance::TryLock(const std::string &lockName) +{ + LogPedantic("Locking single instance: " << lockName); + + struct flock lock; + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 1; + + // Open lock file + m_fdLock = + TEMP_FAILURE_RETRY(open((std::string(LOCK_PREFIX_PATH) + + lockName).c_str(), + O_WRONLY | O_CREAT, 0666)); + + if (m_fdLock == -1) { + ThrowMsg(Exception::LockError, "Cannot open single instance lock file!"); + } + + // Lock file + int result = TEMP_FAILURE_RETRY(fcntl(m_fdLock, F_SETLK, &lock)); + + // Was the instance successfuly locked ? + if (result == 0) { + LogPedantic("Instance locked: " << lockName); + + // It is locked now + m_locked = true; + + // Done + return true; + } + + if (errno == EACCES || errno == EAGAIN) { + LogPedantic("Instance is already running: " << lockName); + return false; + } + + // This is lock error + ThrowMsg(Exception::LockError, "Cannot lock single instance lock file!"); +} + +void SingleInstance::Release() +{ + if (!m_locked) { + return; + } + + LogPedantic("Unlocking single instance"); + + // Unlock file + struct flock lock; + + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 1; + + int result = TEMP_FAILURE_RETRY(fcntl(m_fdLock, F_SETLK, &lock)); + + // Was the instance successfuly unlocked ? + if (result == -1) { + ThrowMsg(Exception::LockError, + "Cannot unlock single instance lock file!"); + } + + // Close lock file + if (TEMP_FAILURE_RETRY(close(m_fdLock)) == -1) { + ThrowMsg(Exception::LockError, + "Cannot close single instance lock file!"); + } + + m_fdLock = -1; + + // Done + m_locked = false; + LogPedantic("Instance unlocked"); +} +} // namespace DPL diff --git a/modules/core/src/singleton.cpp b/modules/core/src/singleton.cpp new file mode 100644 index 0000000..a76e8ac --- /dev/null +++ b/modules/core/src/singleton.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_event.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/string.cpp b/modules/core/src/string.cpp new file mode 100644 index 0000000..e81ae22 --- /dev/null +++ b/modules/core/src/string.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file string.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// TODO: Completely move to ICU +namespace DPL { +namespace //anonymous +{ +class ASCIIValidator +{ + const std::string& m_TestedString; + + public: + ASCIIValidator(const std::string& aTestedString); + + void operator()(char aCharacter) const; +}; + +ASCIIValidator::ASCIIValidator(const std::string& aTestedString) : + m_TestedString(aTestedString) +{} + +void ASCIIValidator::operator()(char aCharacter) const +{ + // Check for ASCII data range + if (aCharacter <= 0) { + ThrowMsg( + StringException::InvalidASCIICharacter, + "invalid character code " << static_cast(aCharacter) + << " from string [" << + m_TestedString + << "] passed as ASCII"); + } +} + +const iconv_t gc_IconvOperError = reinterpret_cast(-1); +const size_t gc_IconvConvertError = static_cast(-1); +} // namespace anonymous + +String FromUTF8String(const std::string& aIn) +{ + if (aIn.empty()) { + return String(); + } + + size_t inbytes = aIn.size(); + + // Default iconv UTF-32 module adds BOM (4 bytes) in from of string + // The worst case is when 8bit UTF-8 char converts to 32bit UTF-32 + // newsize = oldsize * 4 + end + bom + // newsize - bytes for UTF-32 string + // oldsize - letters in UTF-8 string + // end - end character for UTF-32 (\0) + // bom - Unicode header in front of string (0xfeff) + size_t outbytes = sizeof(wchar_t) * (inbytes + 2); + std::vector output(inbytes + 2, 0); + + size_t outbytesleft = outbytes; + char* inbuf = const_cast(aIn.c_str()); + + // vector is used to provide buffer for iconv which expects char* buffer + // but during conversion from UTF32 uses internaly wchar_t + char* outbuf = reinterpret_cast(&output[0]); + + iconv_t iconvHandle = iconv_open("UTF-32", "UTF-8"); + + if (gc_IconvOperError == iconvHandle) { + int error = errno; + + ThrowMsg(StringException::IconvInitErrorUTF8ToUTF32, + "iconv_open failed for " << "UTF-32 <- UTF-8" << + "error: " << GetErrnoString(error)); + } + + size_t iconvRet = iconv(iconvHandle, + &inbuf, + &inbytes, + &outbuf, + &outbytesleft); + + iconv_close(iconvHandle); + + if (gc_IconvConvertError == iconvRet) { + ThrowMsg(StringException::IconvConvertErrorUTF8ToUTF32, + "iconv failed for " << "UTF-32 <- UTF-8" << "error: " + << GetErrnoString()); + } + + // Ignore BOM in front of UTF-32 + return &output[1]; +} + +std::string ToUTF8String(const DPL::String& aIn) +{ + if (aIn.empty()) { + return std::string(); + } + + size_t inbytes = aIn.size() * sizeof(wchar_t); + size_t outbytes = inbytes + sizeof(char); + + // wstring returns wchar_t but iconv expects char* + // iconv internally is processing input as wchar_t + char* inbuf = reinterpret_cast(const_cast(aIn.c_str())); + std::vector output(inbytes, 0); + char* outbuf = &output[0]; + + size_t outbytesleft = outbytes; + + iconv_t iconvHandle = iconv_open("UTF-8", "UTF-32"); + + if (gc_IconvOperError == iconvHandle) { + ThrowMsg(StringException::IconvInitErrorUTF32ToUTF8, + "iconv_open failed for " << "UTF-8 <- UTF-32" + << "error: " << GetErrnoString()); + } + + size_t iconvRet = iconv(iconvHandle, + &inbuf, + &inbytes, + &outbuf, + &outbytesleft); + + iconv_close(iconvHandle); + + if (gc_IconvConvertError == iconvRet) { + ThrowMsg(StringException::IconvConvertErrorUTF32ToUTF8, + "iconv failed for " << "UTF-8 <- UTF-32" + << "error: " << GetErrnoString()); + } + + return &output[0]; +} + +String FromASCIIString(const std::string& aString) +{ + String output; + + std::for_each(aString.begin(), aString.end(), ASCIIValidator(aString)); + std::copy(aString.begin(), aString.end(), std::back_inserter(output)); + + return output; +} + +String FromUTF32String(const std::wstring& aString) +{ + return String(&aString[0]); +} + +static UChar *ConvertToICU(const String &inputString) +{ + ScopedArray outputString; + int32_t size = 0; + int32_t convertedSize = 0; + UErrorCode error = U_ZERO_ERROR; + + // Calculate size of output string + ::u_strFromWCS(NULL, + 0, + &size, + inputString.c_str(), + -1, + &error); + + if (error == U_ZERO_ERROR || + error == U_BUFFER_OVERFLOW_ERROR) + { + // What buffer size is ok ? + LogPedantic("ICU: Output buffer size: " << size); + } else { + ThrowMsg(StringException::ICUInvalidCharacterFound, + "ICU: Failed to retrieve output string size. Error: " + << error); + } + + // Allocate proper buffer + outputString.Reset(new UChar[size + 1]); + ::memset(outputString.Get(), 0, sizeof(UChar) * (size + 1)); + + error = U_ZERO_ERROR; + + // Do conversion + ::u_strFromWCS(outputString.Get(), + size + 1, + &convertedSize, + inputString.c_str(), + -1, + &error); + + if (!U_SUCCESS(error)) { + ThrowMsg(StringException::ICUInvalidCharacterFound, + "ICU: Failed to convert string. Error: " << error); + } + + // Done + return outputString.Release(); +} + +int StringCompare(const String &left, + const String &right, + bool caseInsensitive) +{ + // Convert input strings + ScopedArray leftICU(ConvertToICU(left)); + ScopedArray rightICU(ConvertToICU(right)); + + if (caseInsensitive) { + return static_cast(u_strcasecmp(leftICU.Get(), rightICU.Get(), 0)); + } else { + return static_cast(u_strcmp(leftICU.Get(), rightICU.Get())); + } +} +} //namespace DPL + +std::ostream& operator<<(std::ostream& aStream, const DPL::String& aString) +{ + return aStream << DPL::ToUTF8String(aString); +} diff --git a/modules/core/src/task.cpp b/modules/core/src/task.cpp new file mode 100644 index 0000000..6d4ff0d --- /dev/null +++ b/modules/core/src/task.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file task.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Radoslaw Wicik (r.wicik@samsung.com) + * @version 1.0 + * @brief Implementation file for abstaract task definition + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/thread.cpp b/modules/core/src/thread.cpp new file mode 100644 index 0000000..0e75810 --- /dev/null +++ b/modules/core/src/thread.cpp @@ -0,0 +1,623 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of thread + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace // anonymous +{ +static const size_t NANOSECONDS_PER_SECOND = + static_cast(1000 * 1000 * 1000); + +static const size_t NANOSECONDS_PER_MILISECOND = + static_cast(1000 * 1000); + +static const size_t NANOSECONDS_PER_MICROSECOND = + static_cast(1000); + +static const pthread_t g_mainThread = pthread_self(); + +class ThreadSpecific +{ + public: + pthread_key_t threadSpecific; + + ThreadSpecific() : + threadSpecific(0) + { + threadSpecific = 0; + pthread_key_create(&threadSpecific, NULL); + } + + virtual ~ThreadSpecific() + { + pthread_key_delete(threadSpecific); + } +}; + +static ThreadSpecific g_threadSpecific; +} // namespace anonymous + +namespace DPL { +bool g_TLSforMainCreated = false; + +Thread::Thread() : + m_thread(0), + m_abandon(false), + m_running(false), + m_directInvoke(false) +{} + +Thread::~Thread() +{ + // Ensure that we quit thread + // Always wait thread by yourself; if thread is still running + // this may be sometimes very bad. When derived, some resources + // may leak or be doubly freed + Quit(); + + // Remove any remainig events + // Thread proc is surely not running now + for (InternalEventList::iterator iterator = m_eventList.begin(); + iterator != m_eventList.end(); + ++iterator) + { + iterator->eventDeleteProc(iterator->event, iterator->userParam); + } + + m_eventList.clear(); +} + +bool Thread::IsMainThread() +{ + return (pthread_equal(pthread_self(), g_mainThread)); +} + +Thread *Thread::GetCurrentThread() +{ + if (pthread_equal(pthread_self(), g_mainThread)) { + return NULL; + } + + void *threadSpecific = pthread_getspecific(g_threadSpecific.threadSpecific); + + // Is this a managed thread ? + if (threadSpecific == NULL) { + Throw(Exception::UnmanagedThread); + } + + return static_cast(threadSpecific); +} + +void *Thread::StaticThreadEntry(void *param) +{ + LogPedantic("Entered static thread entry"); + + // Retrieve context + Thread *This = static_cast(param); + Assert(This != NULL); + + // Set thread specific + int result = pthread_setspecific(g_threadSpecific.threadSpecific, This); + + if (result != 0) { + LogError("Failed to set threadSpecific. Error: " << strerror(result)); + } + + // Enter thread proc + // Do not allow exceptions to hit pthread core + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + This->ThreadEntry(); + } + UNHANDLED_EXCEPTION_HANDLER_END + + // Critical section + { + // Leave running state + Mutex::ScopedLock lock(&This->m_stateMutex); + + This->m_running = false; + + // Abandon thread + if (This->m_abandon) { + LogPedantic("Thread was abandoned"); + pthread_detach(This->m_thread); + } else { + LogPedantic("Thread is joinable"); + } + } + + return NULL; +} + +int Thread::ThreadEntry() +{ + LogPedantic("Entered default thread entry"); + return Exec(); +} + +void Thread::ProcessEvents() +{ + LogPedantic("Processing events"); + + // Steal current event list + InternalEventList stolenEvents; + + // Enter event list critical section + { + Mutex::ScopedLock lock(&m_eventMutex); + m_eventList.swap(stolenEvents); + m_eventInvoker.Reset(); + } + + // Process event list + LogPedantic("Stolen " << stolenEvents.size() << " internal events"); + + for (InternalEventList::iterator iterator = stolenEvents.begin(); + iterator != stolenEvents.end(); + ++iterator) + { + // Dispatch immediate event + iterator->eventDispatchProc(iterator->event, iterator->userParam); + + // Delete event + iterator->eventDeleteProc(iterator->event, iterator->userParam); + } +} + +void Thread::ProcessTimedEvents() +{ + // Critical section on timed events mutex + { + Mutex::ScopedLock lock(&m_timedEventMutex); + + // Get current time + unsigned long currentTimeMiliseconds = GetCurrentTimeMiliseconds(); + + // Info + LogPedantic( + "Processing timed events. Time now: " << currentTimeMiliseconds << + " ms"); + + // All timed events are sorted chronologically + // Emit timed out events + while (!m_timedEventVector.empty() && + currentTimeMiliseconds >= + m_timedEventVector.begin()->registerTimeMiliseconds + + m_timedEventVector.begin()->dueTimeMiliseconds) + { + // Info + LogPedantic( + "Transforming timed event into immediate event. Absolute due time: " + << + (m_timedEventVector.begin()->registerTimeMiliseconds + + m_timedEventVector.begin()->dueTimeMiliseconds) << + " ms"); + + // Emit immediate event + PushEvent(m_timedEventVector.begin()->event, + m_timedEventVector.begin()->eventDispatchProc, + m_timedEventVector.begin()->eventDeleteProc, + m_timedEventVector.begin()->userParam); + + // Remove timed eventand fix heap + std::pop_heap(m_timedEventVector.begin(), m_timedEventVector.end()); + m_timedEventVector.pop_back(); + } + } +} + +unsigned long Thread::GetCurrentTimeMiliseconds() const +{ + timeval tv; + gettimeofday(&tv, NULL); + return static_cast(tv.tv_sec) * 1000 + + static_cast(tv.tv_usec) / 1000; +} + +int Thread::Exec() +{ + LogPedantic("Executing thread event processing"); + + const std::size_t MIN_HANDLE_LIST_SIZE = 4; + + // Start processing of events + WaitableHandleListEx handleList; + + // index 0: Quit waitable event handle + handleList.push_back(std::make_pair(m_quitEvent.GetHandle(), WaitMode::Read)); + + // index 1: Event occurred event handle + handleList.push_back(std::make_pair(m_eventInvoker.GetHandle(), + WaitMode::Read)); + + // index 2: Timed event occurred event handle + handleList.push_back(std::make_pair(m_timedEventInvoker.GetHandle(), + WaitMode::Read)); + + // index 3: Waitable handle watch support invoker + handleList.push_back(std::make_pair(WaitableHandleWatchSupport:: + WaitableInvokerHandle(), + WaitMode::Read)); + + // + // Watch list might have been initialized before threaded started + // Need to fill waitable event watch list in this case + // + { + WaitableHandleListEx waitableHandleWatchHandles = + WaitableHandleWatchSupport::WaitableWatcherHandles(); + std::copy( + waitableHandleWatchHandles.begin(), + waitableHandleWatchHandles.end(), std::back_inserter(handleList)); + } + + // Quit flag + bool quit = false; + + while (!quit) { + // Retrieve minimum wait time, according to timed events list + unsigned long minimumWaitTime; + + // Critical section on timed events mutex + { + Mutex::ScopedLock lock(&m_timedEventMutex); + + if (!m_timedEventVector.empty()) { + unsigned long currentTimeMiliseconds = + GetCurrentTimeMiliseconds(); + unsigned long destinationTimeMiliseconds = + m_timedEventVector.begin()->registerTimeMiliseconds + + m_timedEventVector.begin()->dueTimeMiliseconds; + + // Are we already late with timed event ? + if (currentTimeMiliseconds > destinationTimeMiliseconds) { + minimumWaitTime = 0; + } else { + minimumWaitTime = destinationTimeMiliseconds - + currentTimeMiliseconds; + } + } else { + minimumWaitTime = 0xFFFFFFFF; // Infinity + } + } + + // Info + LogPedantic( + "Thread loop minimum wait time: " << minimumWaitTime << " ms"); + + // Do thread waiting + WaitableHandleIndexList waitableHandleIndexList = + WaitForMultipleHandles(handleList, minimumWaitTime); + + if (waitableHandleIndexList.empty()) { + // Timeout occurred. Process timed events. + LogPedantic("Timed event list elapsed invoker"); + ProcessTimedEvents(); + continue; + } + + // Go through each index + for (WaitableHandleIndexList::const_iterator + waitableHandleIndexIterator = waitableHandleIndexList.begin(); + waitableHandleIndexIterator != waitableHandleIndexList.end(); + ++waitableHandleIndexIterator) + { + size_t index = *waitableHandleIndexIterator; + + LogPedantic("Event loop triggered with index: " << index); + + switch (index) { + case 0: + // Quit waitable event handle + quit = true; + break; + + case 1: + // Event occurred event handle + ProcessEvents(); + + // Handle direct invoker + if (m_directInvoke) { + m_directInvoke = false; + + LogPedantic("Handling direct invoker"); + + // Update list + while (handleList.size() > MIN_HANDLE_LIST_SIZE) { + handleList.pop_back(); + } + + // Insert current waitable event handles instead + { + WaitableHandleListEx waitableHandleWatchHandles = + WaitableHandleWatchSupport::WaitableWatcherHandles(); + std::copy( + waitableHandleWatchHandles.begin(), + waitableHandleWatchHandles.end(), + std::back_inserter(handleList)); + } + } + + // Done + break; + + case 2: + // Timed event list changed + LogPedantic("Timed event list changed invoker"); + ProcessTimedEvents(); + + // Reset timed event invoker + m_timedEventInvoker.Reset(); + + // Done + break; + + case 3: + // Waitable handle watch support invoker + LogPedantic("Waitable handle watch invoker event occurred"); + + // First, remove all previous handles + while (handleList.size() > MIN_HANDLE_LIST_SIZE) { + handleList.pop_back(); + } + + // Insert current waitable event handles instead + { + WaitableHandleListEx waitableHandleWatchHandles = + WaitableHandleWatchSupport::WaitableWatcherHandles(); + std::copy( + waitableHandleWatchHandles.begin(), + waitableHandleWatchHandles.end(), + std::back_inserter(handleList)); + } + + // Handle invoker in waitable watch support + WaitableHandleWatchSupport::InvokerFinished(); + + LogPedantic("Waitable handle watch invoker event handled"); + + // Done + break; + + default: + // Waitable event watch list + LogPedantic("Waitable handle watch event occurred"); + + // Handle event in waitable handle watch + { + std::pair handle = handleList[index]; + WaitableHandleWatchSupport::HandleWatcher(handle.first, + handle.second); + } + + if (m_directInvoke) { + m_directInvoke = false; + + LogPedantic("Handling direct invoker"); + + // Update list + while (handleList.size() > MIN_HANDLE_LIST_SIZE) { + handleList.pop_back(); + } + + // Insert current waitable event handles instead + { + WaitableHandleListEx waitableHandleWatchHandles = + WaitableHandleWatchSupport:: + WaitableWatcherHandles(); + std::copy(waitableHandleWatchHandles.begin(), + waitableHandleWatchHandles.end(), + std::back_inserter(handleList)); + } + } + + LogPedantic("Waitable handle watch event handled"); + + // Done + break; + } + } + } + + LogPedantic("Leaving thread event processing"); + return 0; +} + +void Thread::Run() +{ + LogPedantic("Running thread"); + + // Critical section + { + Mutex::ScopedLock lock(&m_stateMutex); + + if (m_running) { + return; + } + + // Try to create new thread + if (pthread_create(&m_thread, NULL, &StaticThreadEntry, this) != 0) { + Throw(Exception::RunFailed); + } + + // At default, we abandon thread + m_abandon = true; + + // Enter running state + m_running = true; + } + + LogPedantic("Thread run"); +} + +void Thread::Quit() +{ + pthread_t joinableThread; + + // Critical section + { + Mutex::ScopedLock lock(&m_stateMutex); + + // Is thread running ? + if (!m_running) { + return; + } + + LogPedantic("Quitting thread..."); + + // Do not abandon thread, we will join + m_abandon = false; + + // Singal quit waitable event + m_quitEvent.Signal(); + + // Copy joinable thread identifier, because + // we are leaving critical section + joinableThread = m_thread; + } + + // Wait for joinable thread + void *result; + + if (pthread_join(joinableThread, &result) != 0) { + Throw(Exception::QuitFailed); + } + + LogPedantic("Thread quit"); +} + +void Thread::PushEvent(void *event, + EventDispatchProc eventDispatchProc, + EventDeleteProc eventDeleteProc, + void *userParam) +{ + // Enter event list critical section + Mutex::ScopedLock lock(&m_eventMutex); + + // Push new event + m_eventList.push_back(InternalEvent(event, userParam, eventDispatchProc, + eventDeleteProc)); + + // Trigger invoker + m_eventInvoker.Signal(); + + LogPedantic("Event pushed and invoker signaled"); +} + +void Thread::PushTimedEvent(void *event, + double dueTimeSeconds, + EventDispatchProc eventDispatchProc, + EventDeleteProc eventDeleteProc, + void *userParam) +{ + // Check for developer errors + Assert(dueTimeSeconds >= 0.0); + + // Enter timed event list critical section + Mutex::ScopedLock lock(&m_timedEventMutex); + + // Get current time + unsigned long currentTimeMiliseconds = GetCurrentTimeMiliseconds(); + + // Convert to miliseconds + unsigned long dueTimeMiliseconds = + static_cast(1000.0 * dueTimeSeconds); + + // Push new timed event + m_timedEventVector.push_back(InternalTimedEvent(event, userParam, + dueTimeMiliseconds, + currentTimeMiliseconds, + eventDispatchProc, + eventDeleteProc)); + + // Heapify timed events + std::make_heap(m_timedEventVector.begin(), m_timedEventVector.end()); + + // Trigger invoker + m_timedEventInvoker.Signal(); + + LogPedantic( + "Timed event pushed and invoker signaled: due time: " << + dueTimeMiliseconds << " ms, absolute due time: " << + currentTimeMiliseconds + dueTimeMiliseconds << " ms"); +} + +Thread *Thread::GetInvokerThread() +{ + return this; +} + +void Thread::HandleDirectInvoker() +{ + // We must be in ProcessEvents call stack + // Mark that situation to handle direct invoker + m_directInvoke = true; +} + +void Thread::Sleep(uint64_t seconds) +{ + NanoSleep(seconds * NANOSECONDS_PER_SECOND); +} + +void Thread::MiliSleep(uint64_t miliseconds) +{ + NanoSleep(miliseconds * NANOSECONDS_PER_MILISECOND); +} + +void Thread::MicroSleep(uint64_t microseconds) +{ + NanoSleep(microseconds * NANOSECONDS_PER_MICROSECOND); +} + +void Thread::NanoSleep(uint64_t nanoseconds) +{ + timespec requestedTime = { + static_cast( + nanoseconds / NANOSECONDS_PER_SECOND), + + static_cast( + nanoseconds % NANOSECONDS_PER_SECOND) + }; + + timespec remainingTime; + + for (;;) { + if (nanosleep(&requestedTime, &remainingTime) == 0) { + break; + } + + int error = errno; + Assert(error == EINTR); + + requestedTime = remainingTime; + } +} +} // namespace DPL diff --git a/modules/core/src/type_list.cpp b/modules/core/src/type_list.cpp new file mode 100644 index 0000000..fa94806 --- /dev/null +++ b/modules/core/src/type_list.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file type_list.cpp + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Generic type list template + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/union_cast.cpp b/modules/core/src/union_cast.cpp new file mode 100644 index 0000000..ffcb499 --- /dev/null +++ b/modules/core/src/union_cast.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file union_cast.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for union cast + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/core/src/waitable_event.cpp b/modules/core/src/waitable_event.cpp new file mode 100644 index 0000000..4808896 --- /dev/null +++ b/modules/core/src/waitable_event.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_event.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable event + */ +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +WaitableEvent::WaitableEvent() +{ + if (pipe(m_pipe) == -1) { + Throw(Exception::CreateFailed); + } + + if (fcntl(m_pipe[0], F_SETFL, O_NONBLOCK | + fcntl(m_pipe[0], F_GETFL)) == -1) + { + Throw(Exception::CreateFailed); + } +} + +WaitableEvent::~WaitableEvent() +{ + if (TEMP_FAILURE_RETRY(close(m_pipe[0])) == -1) { + Throw(Exception::DestroyFailed); + } + + if (TEMP_FAILURE_RETRY(close(m_pipe[1])) == -1) { + Throw(Exception::DestroyFailed); + } +} + +WaitableHandle WaitableEvent::GetHandle() const +{ + return m_pipe[0]; +} + +void WaitableEvent::Signal() const +{ + char data = 0; + + if (TEMP_FAILURE_RETRY(write(m_pipe[1], &data, 1)) != 1) { + Throw(Exception::SignalFailed); + } +} + +void WaitableEvent::Reset() const +{ + char data; + + if (TEMP_FAILURE_RETRY(read(m_pipe[0], &data, 1)) != 1) { + Throw(Exception::ResetFailed); + } +} +} // namespace DPL diff --git a/modules/core/src/waitable_handle.cpp b/modules/core/src/waitable_handle.cpp new file mode 100644 index 0000000..5ea600d --- /dev/null +++ b/modules/core/src/waitable_handle.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_handle.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable handle + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace // anonymous +{ +void CheckWaitableHandle(WaitableHandle handle) +{ +#ifdef DPL_ENABLE_WAITABLE_HANDLE_BADF_CHECK + // Try to get descriptor flags + int result = fcntl(handle, F_GETFL); + + if (result == -1 && errno == EBADF) { + AssertMsg(0, "CheckWaitableHandle: Invalid WaitableHandle! (EBADF)"); + } + + AssertMsg(result != -1, "CheckWaitableHandle: Invalid WaitableHandle!"); +#endif // DPL_ENABLE_WAITABLE_HANDLE_BADF_CHECK +} +} // namespace anonymous + +WaitableHandleIndexList WaitForSingleHandle(WaitableHandle handle, + unsigned long miliseconds) +{ + WaitableHandleList waitHandles; + waitHandles.push_back(handle); + return WaitForMultipleHandles(waitHandles, miliseconds); +} + +WaitableHandleIndexList WaitForSingleHandle(WaitableHandle handle, + WaitMode::Type mode, + unsigned long miliseconds) +{ + WaitableHandleListEx waitHandles; + waitHandles.push_back(std::make_pair(handle, mode)); + return WaitForMultipleHandles(waitHandles, miliseconds); +} + +WaitableHandleIndexList WaitForMultipleHandles( + const WaitableHandleList &waitableHandleList, + unsigned long miliseconds) +{ + WaitableHandleListEx handleList; + + for (WaitableHandleList::const_iterator iterator = waitableHandleList.begin(); + iterator != waitableHandleList.end(); + ++iterator) + { + // Wait for multiple objects + handleList.push_back(std::make_pair(*iterator, WaitMode::Read)); + } + + // Do waiting + return WaitForMultipleHandles(handleList, miliseconds); +} + +WaitableHandleIndexList WaitForMultipleHandles( + const WaitableHandleListEx &waitableHandleListEx, + unsigned long miliseconds) +{ + fd_set readFds, writeFds, errorFds; + + // Fill sets + int maxFd = -1; + + FD_ZERO(&readFds); + FD_ZERO(&writeFds); + FD_ZERO(&errorFds); + + // Add read wait handles + for (WaitableHandleListEx::const_iterator iterator = + waitableHandleListEx.begin(); + iterator != waitableHandleListEx.end(); + ++iterator) + { + if (iterator->first > maxFd) { + maxFd = iterator->first; + } + + CheckWaitableHandle(iterator->first); + + // Handle errors along with read and write events + FD_SET(iterator->first, &errorFds); + + if (iterator->second == WaitMode::Read) { + FD_SET(iterator->first, &readFds); + } else if (iterator->second == WaitMode::Write) { + FD_SET(iterator->first, &writeFds); + } + } + + // Do select + timeval timeout; + timeval *effectiveTimeout = NULL; + if (miliseconds != 0xFFFFFFFF) { + timeout.tv_sec = miliseconds / 1000; + timeout.tv_usec = (miliseconds % 1000) * 1000; + effectiveTimeout = &timeout; + } + + if (TEMP_FAILURE_RETRY(select(maxFd + 1, &readFds, &writeFds, &errorFds, + effectiveTimeout)) == -1) + { + Throw(WaitFailed); + } + + // Check results + WaitableHandleIndexList indexes; + size_t index = 0; + + for (WaitableHandleListEx::const_iterator iterator = + waitableHandleListEx.begin(); + iterator != waitableHandleListEx.end(); + ++iterator) + { + // Always return errors, no matter what type of listening is set + if (FD_ISSET(iterator->first, &errorFds)) { + indexes.push_back(index); + } else if (iterator->second == WaitMode::Read) { + if (FD_ISSET(iterator->first, &readFds)) { + indexes.push_back(index); + } + } else if (iterator->second == WaitMode::Write) { + if (FD_ISSET(iterator->first, &writeFds)) { + indexes.push_back(index); + } + } + ++index; + } + + // Successfuly awaited some events or timeout occurred + return indexes; +} +} // namespace DPL diff --git a/modules/core/src/waitable_handle_watch_support.cpp b/modules/core/src/waitable_handle_watch_support.cpp new file mode 100644 index 0000000..53f8b65 --- /dev/null +++ b/modules/core/src/waitable_handle_watch_support.cpp @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_handle_watch_support.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable handle watch + * support + */ +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +WaitableHandleWatchSupport::WaitableHandleWatchSupport() +{} + +WaitableHandleWatchSupport::~WaitableHandleWatchSupport() +{ + // Developer assertions + if (!m_watchersMap.empty()) { + LogWarning("### Leaked watchers map dump ###"); + + for (WaitableHandleWatchersMap::const_iterator iterator = + m_watchersMap.begin(); + iterator != m_watchersMap.end(); + ++iterator) + { + LogWarning("### Waitable handle: " << iterator->first); + + LogWarning( + "### Read listeners: " << + iterator->second.readListenersCount); + LogWarning( + "### Write listeners: " << + iterator->second.writeListenersCount); + + for (WaitableHandleListenerList::const_iterator listenersIterator = + iterator->second.listeners.begin(); + listenersIterator != iterator->second.listeners.end(); + ++listenersIterator) + { + LogWarning( + "### Mode: " << listenersIterator->mode << + ". Listener: 0x" << std::hex << listenersIterator->listener); + } + } + } +} + +WaitableHandle WaitableHandleWatchSupport::WaitableInvokerHandle() const +{ + return m_watchersInvoker.GetHandle(); +} + +WaitableHandleListEx WaitableHandleWatchSupport::WaitableWatcherHandles() const +{ + // Critical section + { + RecursiveMutex::ScopedLock lock(&m_watchersMutex); + + WaitableHandleListEx handleList; + + for (WaitableHandleWatchersMap::const_iterator iterator = + m_watchersMap.begin(); + iterator != m_watchersMap.end(); + ++iterator) + { + // Register waitable event id for wait + // Check if there are any read listeners and write listeners + // and register for both if applicable + if (iterator->second.readListenersCount > 0) { + handleList.push_back(std::make_pair(iterator->first, + WaitMode::Read)); + } + + if (iterator->second.writeListenersCount > 0) { + handleList.push_back(std::make_pair(iterator->first, + WaitMode::Write)); + } + } + + return handleList; + } +} + +void WaitableHandleWatchSupport::InvokerFinished() +{ + LogPedantic("Invoker finished called"); + + // Reset invoker + m_watchersInvoker.Reset(); + + // Commit invoke + m_watchersInvokerCommit.Signal(); +} + +void WaitableHandleWatchSupport::HandleWatcher(WaitableHandle waitableHandle, + WaitMode::Type mode) +{ + // + // Waitable event occurred + // Now call all listeners for that waitable event. It is possible + // that some of listeners early disappeared. This is not a problem. + // Warning: Listeners and/or watcher may also disappear during dispatching + // handlers! + // + LogPedantic("Waitable event occurred"); + + // Critical section for other threads + { + RecursiveMutex::ScopedLock lock(&m_watchersMutex); + + // Notice: We must carefully call watchers here as they may disappear + // (zero listeners) or be created during each of handler call + // All removed listeners are handled correctly. Adding + // additional listener to the same waitable handle + // during handler dispatch sequence is _not_ supported. + WaitableHandleWatchersMap trackedWatchers = m_watchersMap; + + for (WaitableHandleWatchersMap::const_iterator trackedWatchersIterator + = trackedWatchers.begin(); + trackedWatchersIterator != trackedWatchers.end(); + ++trackedWatchersIterator) + { + // Check if this watcher still exists + // If not, go to next tracked watcher + if (m_watchersMap.find(trackedWatchersIterator->first) == + m_watchersMap.end()) + { + LogPedantic("Watcher disappeared during watcher handler"); + continue; + } + + // Is this is a waitable handle that we are searching for ? + if (waitableHandle != trackedWatchersIterator->first) { + continue; + } + + // Track watcher listeners list + WaitableHandleListenerList trackedListeners = + trackedWatchersIterator->second.listeners; + + LogPedantic( + "Calling waitable event listeners (" << + trackedListeners.size() << ")..."); + + // Notice: We must carefully call listeners here as they may + // disappear or be created during each of handler call + // All removed listeners are handled correctly. Adding + // additional listener to the same waitable handle + // during handler dispatch sequence is should be also + // handled, as an extremly case. + + // Call all waitable event listeners who listen for that event + for (WaitableHandleListenerList::const_iterator + trackedListenersIterator = trackedListeners.begin(); + trackedListenersIterator != trackedListeners.end(); + ++trackedListenersIterator) + { + // Check if this watcher still exists + // If not, there cannot be another one. Must exit now (after + // break, we actually exit) + if (m_watchersMap.find(trackedWatchersIterator->first) == + m_watchersMap.end()) + { + LogPedantic("Watcher disappeared during watcher handler"); + break; + } + + // Check if this watcher listener still exists + // If not, go to next tracked watcher listener + bool listenerStillExists = false; + + for (WaitableHandleListenerList::const_iterator + searchListenerIterator = + trackedWatchersIterator->second.listeners.begin(); + searchListenerIterator != + trackedWatchersIterator->second.listeners.end(); + ++searchListenerIterator) + { + if (searchListenerIterator->listener == + trackedListenersIterator->listener && + searchListenerIterator->mode == + trackedListenersIterator->mode) + { + listenerStillExists = true; + break; + } + } + + if (!listenerStillExists) { + LogPedantic( + "Watcher listener disappeared during watcher handler"); + break; + } + + // Is this is a listener mode that we are searching for ? + if (mode != trackedListenersIterator->mode) { + continue; + } + + // Call waitable event watch listener + LogPedantic("Before tracker listener call..."); + trackedListenersIterator->listener->OnWaitableHandleEvent( + trackedWatchersIterator->first, + trackedListenersIterator->mode); + LogPedantic("After tracker listener call..."); + } + + // Now call all those listeners who registered during listener calls + // FIXME: Implement! Notice, that scenario may be recursive! + + LogPedantic("Waitable event listeners called"); + + // No more waitable events possible - consistency check + break; + } + } +} + +void WaitableHandleWatchSupport::AddWaitableHandleWatch( + WaitableHandleListener* listener, + WaitableHandle waitableHandle, + WaitMode::Type mode) +{ + // Enter waitable event list critical section + RecursiveMutex::ScopedLock lock(&m_watchersMutex); + + // Find proper list to register into + WaitableHandleWatchersMap::iterator mapIterator = m_watchersMap.find( + waitableHandle); + + if (mapIterator != m_watchersMap.end()) { + // Assert if there is no such listener already that is listening in this + // mode + for (WaitableHandleListenerList::iterator listenersIterator = + mapIterator->second.listeners.begin(); + listenersIterator != mapIterator->second.listeners.end(); + ++listenersIterator) + { + // Must not insert same listener-mode pair + Assert( + listenersIterator->listener != listener || + listenersIterator->mode != mode); + } + } + + LogPedantic("Adding waitable handle watch: " << waitableHandle); + + // Push new waitable event watch + if (mapIterator != m_watchersMap.end()) { + mapIterator->second.listeners.push_back(WaitableHandleWatcher(listener, + mode)); + } else { + m_watchersMap[waitableHandle].listeners.push_back(WaitableHandleWatcher( + listener, mode)); + } + + // Update counters + switch (mode) { + case WaitMode::Read: + m_watchersMap[waitableHandle].readListenersCount++; + break; + + case WaitMode::Write: + m_watchersMap[waitableHandle].writeListenersCount++; + break; + + default: + Assert(0); + } + + // Trigger waitable event invoker to commit changes + CommitInvoker(); + + LogPedantic("Waitable event watch added and invoker signaled"); +} + +void WaitableHandleWatchSupport::RemoveWaitableHandleWatch( + WaitableHandleListener *listener, + WaitableHandle waitableHandle, + WaitMode::Type mode) +{ + // Enter waitable event list critical section + RecursiveMutex::ScopedLock lock(&m_watchersMutex); + + // Find proper list with listener + WaitableHandleWatchersMap::iterator mapIterator = m_watchersMap.find( + waitableHandle); + + Assert(mapIterator != m_watchersMap.end()); + + // Assert if there is such listener and mode + WaitableHandleListenerList::iterator listIterator = + mapIterator->second.listeners.end(); + + for (WaitableHandleListenerList::iterator listenersIterator = + mapIterator->second.listeners.begin(); + listenersIterator != mapIterator->second.listeners.end(); + ++listenersIterator) + { + // Check same pair listener-mode + if (listenersIterator->listener == listener && + listenersIterator->mode == mode) + { + listIterator = listenersIterator; + break; + } + } + + // Same pair listener-mode must exist + Assert(listIterator != mapIterator->second.listeners.end()); + + LogPedantic("Removing waitable handle watch: " << waitableHandle); + + // Remove waitable event watch + mapIterator->second.listeners.erase(listIterator); + + // Update counters + switch (mode) { + case WaitMode::Read: + mapIterator->second.readListenersCount--; + break; + + case WaitMode::Write: + mapIterator->second.writeListenersCount--; + break; + + default: + Assert(0); + } + + // If list is empty, remove it too + if (mapIterator->second.listeners.empty()) { + m_watchersMap.erase(mapIterator); + } + + // Trigger waitable event invoker to commit changes + CommitInvoker(); + + LogPedantic("Waitable event watch removed and invoker signaled"); +} + +void WaitableHandleWatchSupport::CommitInvoker() +{ + // Check calling context and execute invoker + if (Thread::GetCurrentThread() == GetInvokerThread()) { + LogPedantic("Calling direct invoker"); + + // Direct invoker call + HandleDirectInvoker(); + } else { + LogPedantic("Calling indirect invoker"); + + // Indirect invoker call + m_watchersInvoker.Signal(); + + WaitableHandleList waitHandles; + waitHandles.push_back(m_watchersInvokerCommit.GetHandle()); + WaitForMultipleHandles(waitHandles); + + m_watchersInvokerCommit.Reset(); + } +} + +WaitableHandleWatchSupport *WaitableHandleWatchSupport::InheritedContext() +{ + // In threaded context, return thread waitable handle watch implementation + // In main loop, return main waitable handle watch implementation + if (Thread::GetCurrentThread() != NULL) { + return Thread::GetCurrentThread(); + } else { + return &MainSingleton::Instance(); + } +} +} // namespace DPL diff --git a/modules/core/src/zip_input.cpp b/modules/core/src/zip_input.cpp new file mode 100644 index 0000000..fadc60f --- /dev/null +++ b/modules/core/src/zip_input.cpp @@ -0,0 +1,637 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file zip_input.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of zip input + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace // anonymous +{ +const size_t EXTRACT_BUFFER_SIZE = 4096; + +class ScopedUnzClose +{ + private: + unzFile m_file; + + public: + ScopedUnzClose(unzFile file) : + m_file(file) + {} + + ~ScopedUnzClose() + { + if (!m_file) { + return; + } + + if (unzClose(m_file) != UNZ_OK) { + LogPedantic("Failed to close zip input file"); + } + } + + unzFile Release() + { + unzFile file = m_file; + + m_file = NULL; + + return file; + } +}; +} // namespace anonymous + +/* + * Seekable multiplexing device + * + * Explanation: + * Minizip library lacks serious support for multithreaded + * access to zip files. Thus, they cannot be easily extracted + * simulateously. Here is introduced seekable device which does + * have a context with seek index for each file. File is mapped to + * memory and because of that no real synchronization is needed. + * Memory addresses can be indexed. + * + * About generalization: + * To achieve the same results on abstract input device, there must be + * provided a mechanism to read data from random address without + * synchronization. + * In other words: stateless. As described above, stateless property can be + * achieved via memory mapping. + */ +class Device +{ + private: + int m_handle; + off64_t m_size; // file mapping size + unsigned char *m_address; // mapping base address + + struct File + { + off64_t offset; + Device *device; + + File(Device *d) : + offset(0), + device(d) + {} + }; + + public: + Device(const std::string &fileName) + { + LogPedantic("Creating file mapping"); + // Open device and map it to user space + int file = TEMP_FAILURE_RETRY(open(fileName.c_str(), O_RDONLY)); + + if (file == -1) { + int error = errno; + ThrowMsg(ZipInput::Exception::OpenFailed, + "Failed to open file. errno = " << error); + } + + // Scoped close on file + ScopedClose scopedClose(file); + + // Calculate file size + off64_t size = lseek64(file, 0, SEEK_END); + + if (size == static_cast(-1)) { + int error = errno; + ThrowMsg(ZipInput::Exception::OpenFailed, + "Failed to seek file. errno = " << error); + } + + // Map file to usespace + void *address = mmap(0, static_cast(size), + PROT_READ, MAP_SHARED, file, 0); + + if (address == MAP_FAILED) { + int error = errno; + ThrowMsg(ZipInput::Exception::OpenFailed, + "Failed to map file. errno = " << error); + } + + // Release scoped close + m_handle = scopedClose.Release(); + + // Save mapped up address + m_size = size; + m_address = static_cast(address); + + LogPedantic("Created file mapping: " << fileName << + " of size: " << m_size << + " at address: " << std::hex << + static_cast(m_address)); + } + + ~Device() + { + // Close mapping + if (munmap(m_address, static_cast(m_size)) == -1) { + int error = errno; + LogPedantic("Failed to munmap file. errno = " << error); + } + + // Close file descriptor + if (close(m_handle) == -1) { + int error = errno; + LogPedantic("Failed to close file. errno = " << error); + } + } + + // zlib_filefunc64_def interface: files + static voidpf ZCALLBACK open64_file(voidpf opaque, + const void* /*filename*/, + int /*mode*/) + { + Device *device = static_cast(opaque); + + // Open file for master device + return new File(device); + } + + static uLong ZCALLBACK read_file(voidpf opaque, + voidpf pstream, + void* buf, + uLong size) + { + Device *device = static_cast(opaque); + File *deviceFile = static_cast(pstream); + + // Check if offset is out of bounds + if (deviceFile->offset >= device->m_size) { + LogPedantic("Device: read offset out of bounds"); + return -1; + } + + off64_t bytesLeft = device->m_size - + deviceFile->offset; + + off64_t bytesToRead; + + // Calculate bytes to read + if (static_cast(size) > bytesLeft) { + bytesToRead = bytesLeft; + } else { + bytesToRead = static_cast(size); + } + + // Do copy + memcpy(buf, + device->m_address + deviceFile->offset, + static_cast(bytesToRead)); + + // Increment file offset + deviceFile->offset += bytesToRead; + + // Return bytes that were actually read + return static_cast(bytesToRead); + } + + static uLong ZCALLBACK write_file(voidpf /*opaque*/, + voidpf /*stream*/, + const void* /*buf*/, + uLong /*size*/) + { + // Not supported by device + LogPedantic("Unsupported function called!"); + return -1; + } + + static int ZCALLBACK close_file(voidpf /*opaque*/, voidpf stream) + { + File *deviceFile = static_cast(stream); + + // Delete file + delete deviceFile; + + // Always OK + return 0; + } + + static int ZCALLBACK testerror_file(voidpf /*opaque*/, voidpf /*stream*/) + { + // No errors + return 0; + } + + static ZPOS64_T ZCALLBACK tell64_file(voidpf /*opaque*/, voidpf stream) + { + File *deviceFile = static_cast(stream); + + return static_cast(deviceFile->offset); + } + + static long ZCALLBACK seek64_file(voidpf opaque, + voidpf stream, + ZPOS64_T offset, + int origin) + { + Device *device = static_cast(opaque); + File *deviceFile = static_cast(stream); + + switch (origin) { + case ZLIB_FILEFUNC_SEEK_SET: + deviceFile->offset = static_cast(offset); + + break; + + case ZLIB_FILEFUNC_SEEK_CUR: + deviceFile->offset += static_cast(offset); + + break; + + case ZLIB_FILEFUNC_SEEK_END: + deviceFile->offset = + device->m_size - + static_cast(offset); + + break; + + default: + return -1; + } + + return 0; + } +}; + +ZipInput::ZipInput(const std::string &fileName) : + m_device(NULL), + m_numberOfFiles(0), + m_globalComment(), + m_totalUncompressedSize(0), + m_fileInfos() +{ + LogPedantic("Zip input file: " << fileName); + + // Create master device + LogPedantic("Creating master device"); + std::unique_ptr device(new Device(fileName)); + + // Open master file + zlib_filefunc64_def interface; + interface.zopen64_file = &Device::open64_file; + interface.zread_file = &Device::read_file; + interface.zwrite_file = &Device::write_file; + interface.ztell64_file = &Device::tell64_file; + interface.zseek64_file = &Device::seek64_file; + interface.zclose_file = &Device::close_file; + interface.zerror_file = &Device::testerror_file; + interface.opaque = device.get(); + + LogPedantic("Opening zip file"); + unzFile file = unzOpen2_64(NULL, &interface); + + if (file == NULL) { + LogPedantic("Failed to open zip file"); + + // Some errror occured + ThrowMsg(Exception::OpenFailed, + "Failed to open zip file: " << fileName); + } + + // Begin scope + ScopedUnzClose scopedUnzClose(file); + + // Read contents + ReadGlobalInfo(file); + ReadGlobalComment(file); + ReadInfos(file); + + // Release scoped unz close + m_masterFile = scopedUnzClose.Release(); + m_device = device.release(); + + LogPedantic("Zip file opened"); +} + +ZipInput::~ZipInput() +{ + // Close zip + if (unzClose(static_cast(m_masterFile)) != UNZ_OK) { + LogPedantic("Failed to close zip input file"); + } + + // Close device + delete m_device; +} + +void ZipInput::ReadGlobalInfo(void *masterFile) +{ + // Read number of entries and global comment + unz_global_info globalInfo; + + if (unzGetGlobalInfo(static_cast(masterFile), + &globalInfo) != UNZ_OK) + { + LogPedantic("Failed to read zip global info"); + + ThrowMsg(Exception::ReadGlobalInfoFailed, + "Failed to read global info"); + } + + m_numberOfFiles = static_cast(globalInfo.number_entry); + m_globalCommentSize = static_cast(globalInfo.size_comment); + + LogPedantic("Number of files: " << m_numberOfFiles); + LogPedantic("Global comment size: " << m_globalCommentSize); +} + +void ZipInput::ReadGlobalComment(void *masterFile) +{ + ScopedArray comment(new char[m_globalCommentSize + 1]); + + if (unzGetGlobalComment(static_cast(masterFile), + comment.Get(), + m_globalCommentSize + 1) != UNZ_OK) + { + LogPedantic("Failed to read zip global comment"); + + ThrowMsg(Exception::ReadGlobalCommentFailed, + "Failed to read global comment"); + } + + m_globalComment = comment.Get(); + LogPedantic("Global comment: " << m_globalComment); +} + +void ZipInput::ReadInfos(void *masterFile) +{ + // Read infos + m_fileInfos.reserve(m_numberOfFiles); + + if (unzGoToFirstFile(static_cast(masterFile)) != UNZ_OK) { + LogPedantic("Failed to go to first file"); + ThrowMsg(Exception::SeekFileFailed, "Failed to seek first file"); + } + + for (size_t i = 0; i < m_numberOfFiles; ++i) { + unz_file_pos_s filePos; + + if (unzGetFilePos(static_cast(masterFile), + &filePos) != UNZ_OK) + { + LogPedantic("Failed to get file pos"); + ThrowMsg(Exception::FileInfoFailed, "Failed to get zip file info"); + } + + unz_file_info64 fileInfo; + + if (unzGetCurrentFileInfo64(static_cast(masterFile), + &fileInfo, + NULL, + 0, + NULL, + 0, + NULL, + 0) != UNZ_OK) + { + LogPedantic("Failed to get file pos"); + ThrowMsg(Exception::FileInfoFailed, "Failed to get zip file info"); + } + + ScopedArray fileName(new char[fileInfo.size_filename + 1]); + ScopedArray fileComment(new char[fileInfo.size_file_comment + 1]); + + if (unzGetCurrentFileInfo64(static_cast(masterFile), + &fileInfo, + fileName.Get(), + fileInfo.size_filename + 1, + NULL, + 0, + fileComment.Get(), + fileInfo.size_file_comment + 1) != UNZ_OK) + { + LogPedantic("Failed to get file pos"); + ThrowMsg(Exception::FileInfoFailed, "Failed to get zip file info"); + } + + m_fileInfos.push_back( + FileInfo( + FileHandle( + static_cast(filePos.pos_in_zip_directory), + static_cast(filePos.num_of_file) + ), + std::string(fileName.Get()), + std::string(fileComment.Get()), + static_cast(fileInfo.compressed_size), + static_cast(fileInfo.uncompressed_size) + ) + ); + m_totalUncompressedSize += static_cast(fileInfo.uncompressed_size); + + // If this is not the last file, go to next one + if (i != m_numberOfFiles - 1) { + if (unzGoToNextFile( + static_cast(masterFile)) != UNZ_OK) + { + LogPedantic("Failed to go to next file"); + + ThrowMsg(Exception::FileInfoFailed, + "Failed to go to next file"); + } + } + } +} + +ZipInput::const_iterator ZipInput::begin() const +{ + return m_fileInfos.begin(); +} + +ZipInput::const_iterator ZipInput::end() const +{ + return m_fileInfos.end(); +} + +ZipInput::const_reverse_iterator ZipInput::rbegin() const +{ + return m_fileInfos.rbegin(); +} + +ZipInput::const_reverse_iterator ZipInput::rend() const +{ + return m_fileInfos.rend(); +} + +ZipInput::size_type ZipInput::size() const +{ + return m_fileInfos.size(); +} + +ZipInput::File *ZipInput::OpenFile(const std::string &fileName) +{ + FOREACH(iterator, m_fileInfos) + { + if (iterator->name == fileName) { + return new File(m_device, iterator->handle); + } + } + + ThrowMsg(Exception::OpenFileFailed, + "Failed to open zip file: " << fileName); +} + +ZipInput::File::File(class Device *device, FileHandle handle) +{ + // Open file file + zlib_filefunc64_def interface; + interface.zopen64_file = &Device::open64_file; + interface.zread_file = &Device::read_file; + interface.zwrite_file = &Device::write_file; + interface.ztell64_file = &Device::tell64_file; + interface.zseek64_file = &Device::seek64_file; + interface.zclose_file = &Device::close_file; + interface.zerror_file = &Device::testerror_file; + interface.opaque = device; + + LogPedantic("Opening zip file"); + unzFile file = unzOpen2_64(NULL, &interface); + + if (file == NULL) { + LogPedantic("Failed to open zip file"); + + // Some errror occured + ThrowMsg(ZipInput::Exception::OpenFileFailed, + "Failed to open zip file"); + } + + // Begin scope + ScopedUnzClose scopedUnzClose(file); + + // Look up file handle + unz64_file_pos filePos = { + static_cast(handle.first), + static_cast(handle.second) + }; + + if (unzGoToFilePos64(file, &filePos) != UNZ_OK) { + LogPedantic("Failed to seek to zip file"); + + // Some errror occured + ThrowMsg(ZipInput::Exception::OpenFileFailed, + "Failed to seek into zip file"); + } + + // Open current file for reading + if (unzOpenCurrentFile(file) != UNZ_OK) { + LogPedantic("Failed to open current zip file"); + + // Some errror occured + ThrowMsg(ZipInput::Exception::OpenFileFailed, + "Failed to open current zip file"); + } + + // Release scoped unz close + m_file = scopedUnzClose.Release(); + + LogPedantic("Zip file opened"); +} + +ZipInput::File::~File() +{ + // Close current file for reading + if (unzCloseCurrentFile(static_cast(m_file)) != UNZ_OK) { + LogPedantic("Failed to close current zip input file"); + } + + // Close zip file + if (unzClose(static_cast(m_file)) != UNZ_OK) { + LogPedantic("Failed to close zip input file"); + } +} + +DPL::BinaryQueueAutoPtr ZipInput::File::Read(size_t size) +{ + // Do not even try to unzip if requested zero bytes + if (size == 0) { + return DPL::BinaryQueueAutoPtr(new DPL::BinaryQueue()); + } + + // Calc data to read + size_t sizeToRead = size > EXTRACT_BUFFER_SIZE ? + EXTRACT_BUFFER_SIZE : + size; + + // Extract zip file data (one-copy) + ScopedFree rawBuffer(malloc(sizeToRead)); + + if (!rawBuffer) { + throw std::bad_alloc(); + } + + // Do unpack + int bytes = unzReadCurrentFile(static_cast(m_file), + rawBuffer.Get(), + sizeToRead); + + // Internal unzipper error + if (bytes < 0) { + LogPedantic("Extract failed. Error: " << bytes); + + ThrowMsg(ZipInput::Exception::ReadFileFailed, + "Failed to extract file with error: " << bytes); + } + + // Data was read (may be zero bytes) + DPL::BinaryQueueAutoPtr buffer(new DPL::BinaryQueue()); + + buffer->AppendUnmanaged(rawBuffer.Get(), + static_cast(bytes), + &DPL::BinaryQueue::BufferDeleterFree, + NULL); + + rawBuffer.Release(); + + return buffer; +} + +const std::string &ZipInput::GetGlobalComment() const +{ + return m_globalComment; +} + +bool ZipInput::empty() const +{ + return m_fileInfos.empty(); +} + +size_t ZipInput::GetTotalUncompressedSize() const +{ + return m_totalUncompressedSize; +} +} // namespace DPL diff --git a/modules/custom_handler_dao/CMakeLists.txt b/modules/custom_handler_dao/CMakeLists.txt new file mode 100644 index 0000000..1afddd5 --- /dev/null +++ b/modules/custom_handler_dao/CMakeLists.txt @@ -0,0 +1,83 @@ +SET(TARGET_CUSTOM_HANDLER_DAO_DB "Sqlite3DbCustomHandler") + +ADD_CUSTOM_COMMAND( + OUTPUT ${CMAKE_BINARY_DIR}/modules/custom_handler_dao/database_checksum_custom_handler.h + COMMAND ${CMAKE_SOURCE_DIR}/modules/custom_handler_dao/orm/gen_db_md5.sh + ARGS ${CMAKE_BINARY_DIR}/modules/custom_handler_dao/database_checksum_custom_handler.h + ${CMAKE_SOURCE_DIR}/modules/custom_handler_dao/orm/custom_handler_db + DEPENDS ${CMAKE_SOURCE_DIR}/modules/custom_handler_dao/orm/custom_handler_db + ${CMAKE_SOURCE_DIR}/modules/custom_handler_dao/orm/gen_db_md5.sh + COMMENT "Generating WRT custom handlers database checksum" + ) + +ADD_CUSTOM_COMMAND( OUTPUT .wrt_custom_handler.db + COMMAND rm -f ${CMAKE_CURRENT_BINARY_DIR}/.wrt_custom_handler.db + COMMAND gcc -Wall -include ${CMAKE_BINARY_DIR}/modules/custom_handler_dao/database_checksum_custom_handler.h -I${PROJECT_SOURCE_DIR}/modules/db/include -I${PROJECT_SOURCE_DIR}/modules/custom_handler_dao/orm -E ${PROJECT_SOURCE_DIR}/modules/custom_handler_dao/orm/custom_handler_db_sql_generator.h | grep --invert-match "^#" > ${CMAKE_CURRENT_BINARY_DIR}/wrt_custom_handler_db.sql + COMMAND sqlite3 ${CMAKE_CURRENT_BINARY_DIR}/.wrt_custom_handler.db ".read ${CMAKE_CURRENT_BINARY_DIR}/wrt_custom_handler_db.sql" || rm -f ${CMAKE_CURRENT_BINARY_DIR}/.wrt_custom_handler.db + DEPENDS ${CMAKE_BINARY_DIR}/modules/custom_handler_dao/database_checksum_custom_handler.h ${PROJECT_SOURCE_DIR}/modules/custom_handler_dao/orm/custom_handler_db_sql_generator.h ${PROJECT_SOURCE_DIR}/modules/custom_handler_dao/orm/custom_handler_db + ) + +ADD_CUSTOM_COMMAND( OUTPUT .wrt_custom_handler.db-journal + COMMAND touch + ARGS ${CMAKE_CURRENT_BINARY_DIR}/.wrt_custom_handler.db-journal + ) + +ADD_CUSTOM_TARGET(${TARGET_CUSTOM_HANDLER_DAO_DB} ALL DEPENDS .wrt_custom_handler.db .wrt_custom_handler.db-journal) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/wrt_custom_handler_db.sql DESTINATION share/wrt-engine/) + +############################################################################### + +INCLUDE(FindPkgConfig) + +PKG_CHECK_MODULES(CUSTOM_HANDLER_DAO_DEPS + glib-2.0 + REQUIRED) + +SET(CUSTOM_HANDLER_DAO_INCLUDE_DIRS + ${PROJECT_SOURCE_DIR}/modules/custom_handler_dao/include + ${PROJECT_SOURCE_DIR}/modules/custom_handler_dao/orm + ${PROJECT_SOURCE_DIR}/modules/core/include + ${PROJECT_SOURCE_DIR}/modules/db/include + ${PROJECT_SOURCE_DIR}/modules/log/include +) + + +SET(CUSTOM_HANDLER_DAO_RO_SOURCES + dao/CustomHandlerDatabase.cpp + dao/custom_handler_dao_read_only.cpp +) + +SET(CUSTOM_HANDLER_DAO_RW_SOURCES + dao/custom_handler_dao.cpp +) + + +INCLUDE_DIRECTORIES(${CUSTOM_HANDLER_DAO_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(SYSTEM ${CUSTOM_HANDLER_DAO_DEPS_INCLUDE_DIRS}) + +ADD_LIBRARY(${TARGET_CUSTOM_HANDLER_DAO_RO_LIB} SHARED ${CUSTOM_HANDLER_DAO_RO_SOURCES}) +SET_TARGET_PROPERTIES(${TARGET_CUSTOM_HANDLER_DAO_RO_LIB} PROPERTIES SOVERSION ${API_VERSION} VERSION ${VERSION}) +SET_TARGET_PROPERTIES(${TARGET_CUSTOM_HANDLER_DAO_RO_LIB} PROPERTIES COMPILE_FLAGS "-include ${CMAKE_BINARY_DIR}/modules/custom_handler_dao/database_checksum_custom_handler.h") +TARGET_LINK_LIBRARIES(${TARGET_CUSTOM_HANDLER_DAO_RO_LIB} ${TARGET_CUSTOM_HANDLER_DAO_LIB}) +ADD_DEPENDENCIES(${TARGET_CUSTOM_HANDLER_DAO_RO_LIB} ${TARGET_CUSTOM_HANDLER_DAO_DB}) + +ADD_LIBRARY(${TARGET_CUSTOM_HANDLER_DAO_RW_LIB} SHARED ${CUSTOM_HANDLER_DAO_RW_SOURCES}) +SET_TARGET_PROPERTIES(${TARGET_CUSTOM_HANDLER_DAO_RW_LIB} PROPERTIES SOVERSION ${API_VERSION} VERSION ${VERSION}) +SET_TARGET_PROPERTIES(${TARGET_CUSTOM_HANDLER_DAO_RW_LIB} PROPERTIES COMPILE_FLAGS "-include ${CMAKE_BINARY_DIR}/modules/custom_handler_dao/database_checksum_custom_handler.h") +TARGET_LINK_LIBRARIES(${TARGET_CUSTOM_HANDLER_DAO_RW_LIB} ${TARGET_CUSTOM_HANDLER_DAO_RO_LIB}) +ADD_DEPENDENCIES(${TARGET_CUSTOM_HANDLER_DAO_RW_LIB} ${TARGET_CUSTOM_HANDLER_DAO_DB}) + +INSTALL(TARGETS ${TARGET_CUSTOM_HANDLER_DAO_RO_LIB} DESTINATION lib) +INSTALL(TARGETS ${TARGET_CUSTOM_HANDLER_DAO_RW_LIB} DESTINATION lib) + +INSTALL(FILES + include/wrt-commons/custom-handler-dao-ro/common_dao_types.h + include/wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h + include/wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h + DESTINATION include/dpl-efl/wrt-commons/custom-handler-dao-ro +) + +INSTALL(FILES + include/wrt-commons/custom-handler-dao-rw/custom_handler_dao.h + DESTINATION include/dpl-efl/wrt-commons/custom-handler-dao-rw +) diff --git a/modules/custom_handler_dao/dao/CustomHandlerDatabase.cpp b/modules/custom_handler_dao/dao/CustomHandlerDatabase.cpp new file mode 100644 index 0000000..5f26fd7 --- /dev/null +++ b/modules/custom_handler_dao/dao/CustomHandlerDatabase.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +namespace CustomHandlerDB { +namespace Interface { +namespace { +const char* CustomHandler_DB_DATABASE = "/opt/usr/dbspace/.wrt_custom_handler.db"; +DPL::DB::SqlConnection::Flag::Type CustomHandler_DB_FLAGS = + DPL::DB::SqlConnection::Flag::UseLucene; +} + +DPL::Mutex g_dbQueriesMutex; +DPL::DB::ThreadDatabaseSupport g_dbInterface(CustomHandler_DB_DATABASE, + CustomHandler_DB_FLAGS); + +void attachDatabaseRO() +{ + g_dbInterface.AttachToThread(DPL::DB::SqlConnection::Flag::RO); +} + +void attachDatabaseRW() +{ + g_dbInterface.AttachToThread(DPL::DB::SqlConnection::Flag::RW); +} + +void detachDatabase() +{ + g_dbInterface.DetachFromThread(); +} +} //namespace Interface +} //namespace CustomHandlerDB diff --git a/modules/custom_handler_dao/dao/custom_handler_dao.cpp b/modules/custom_handler_dao/dao/custom_handler_dao.cpp new file mode 100644 index 0000000..6d57771 --- /dev/null +++ b/modules/custom_handler_dao/dao/custom_handler_dao.cpp @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file custom_handler_dao.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the definition of custom handler dao class. + */ + +#include +#include +#include +#include + +using namespace DPL::DB::ORM; +using namespace DPL::DB::ORM::custom_handler; + +namespace CustomHandlerDB { +namespace { +template +void fillRow(T& row, const CustomHandler& handler, const DPL::String& pkgName) +{ + row.Set_app_id(pkgName); + row.Set_target(handler.target); + row.Set_base_url(handler.base_url); + row.Set_url(handler.url); + row.Set_title(handler.title); + row.Set_user_allowed(handler.user_decision); +} +} // namespace + +CustomHandlerDAO::CustomHandlerDAO(const DPL::String& pkgName) : + CustomHandlerDAOReadOnly(pkgName) +{} + +CustomHandlerDAO::~CustomHandlerDAO() +{} + +void CustomHandlerDAO::registerContentHandler(const CustomHandler& handler) +{ + LogDebug("Registering content handler " << handler.target << " " << + handler.base_url); + Try { + if (handler.user_decision & Agreed) { + //need to disable all previous, agreed entries + CUSTOM_HANDLER_DB_SELECT(select, ContentHandlers); + select->Where(And(Equals(handler.target), + Or(Equals(Agreed), + Equals( + AgreedPermanently)) + )); + ContentHandlers::Select::RowList rows = select->GetRowList(); + if (rows.size() > 1) { + //more than one activ content handler - not good. Remove all. + //this should never happen + LogError("Database data incoherent."); + CUSTOM_HANDLER_DB_DELETE(deleteContent, ContentHandlers); + deleteContent->Where(And(Equals( + handler.target), + Or(Equals(Agreed), + Equals( + AgreedPermanently)))); + deleteContent->Execute(); + //all content handlers removed. New one can be inserted + } else if (!rows.empty()) { + //one active handler. Can be updaed + LogDebug("Activ content handler exist. Update"); + CUSTOM_HANDLER_DB_UPDATE(update, ContentHandlers); + update->Where(And(Equals(handler. + target), + Or(Equals( + Agreed), + Equals( + AgreedPermanently)) + )); + ContentHandlers::Row rowToUpdate = rows.front(); + + if (handler.user_decision & DecisionSaved) { + //do not ask about previous one + rowToUpdate.Set_user_allowed(DeclinedPermanently); + } else { + //ask for next time + rowToUpdate.Set_user_allowed(Declined); + } + update->Values(rowToUpdate); + update->Execute(); + } + } + LogDebug("Inserting new content handler"); + ContentHandlers::Row row; + fillRow(row, handler, m_pkgName); + if (getContentHandler(handler.target, handler.url, handler.base_url)) { + LogDebug("Content handler exist. Update its state"); + CUSTOM_HANDLER_DB_UPDATE(updateRow, ContentHandlers); + updateRow->Where(And(Equals(m_pkgName), + And(Equals(handler. + target), + And(Equals(handler. + url), + Equals( + handler.base_url))))); + updateRow->Values(row); + updateRow->Execute(); + LogDebug("updated"); + return; + } + CUSTOM_HANDLER_DB_INSERT(insert, ContentHandlers); + insert->Values(row); + insert->Execute(); + LogDebug("insterted"); + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(CustomHandlerDAO::Exception::DatabaseError, + "Failed to register custom handler"); + } +} + +void CustomHandlerDAO::registerProtocolHandler(const CustomHandler& handler) +{ + LogDebug("Registering protocol handler " << handler.target << " " << + handler.base_url); + Try { + if (handler.user_decision & Agreed) { + //need to disable all previous, agreed entries + CUSTOM_HANDLER_DB_SELECT(select, ProtocolHandlers); + select->Where(And(Equals(handler.target), + Or(Equals(Agreed), + Equals( + AgreedPermanently)) + )); + ProtocolHandlers::Select::RowList rows = select->GetRowList(); + if (rows.size() > 1) { + //more than one activ protocol handler - not good. Remove all. + //this should never happen + LogError("Database data incoherent."); + CUSTOM_HANDLER_DB_DELETE(deleteProtocol, ProtocolHandlers); + deleteProtocol->Where(And(Equals( + handler.target), + Or(Equals(Agreed), + Equals( + AgreedPermanently)))); + deleteProtocol->Execute(); + //all protocol handlers removed. New one can be inserted + } else if (!rows.empty()) { + //one active handler. Can be updaed + CUSTOM_HANDLER_DB_UPDATE(update, ProtocolHandlers); + update->Where(And(Equals(handler. + target), + Or(Equals( + Agreed), + Equals( + AgreedPermanently)) + )); + ProtocolHandlers::Row rowToUpdate = rows.front(); + + if (handler.user_decision & DecisionSaved) { + //do not ask about previous one + rowToUpdate.Set_user_allowed(DeclinedPermanently); + } else { + //ask for next time + rowToUpdate.Set_user_allowed(Declined); + } + update->Values(rowToUpdate); + update->Execute(); + } + } + LogDebug("Inserting new protocol handler"); + ProtocolHandlers::Row row; + fillRow(row, handler, m_pkgName); + if (getProtocolHandler(handler.target, handler.url, + handler.base_url)) + { + LogDebug("Protocol handler exist. Update its state"); + CUSTOM_HANDLER_DB_UPDATE(updateRow, ProtocolHandlers); + updateRow->Where(And(Equals(m_pkgName), + And(Equals(handler. + target), + And(Equals(handler. + url), + Equals( + handler.base_url))))); + updateRow->Values(row); + updateRow->Execute(); + LogDebug("updated"); + return; + } + CUSTOM_HANDLER_DB_INSERT(insert, ProtocolHandlers); + insert->Values(row); + insert->Execute(); + LogDebug("insterted"); + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(CustomHandlerDAO::Exception::DatabaseError, + "Failed to register custom handler"); + } +} + +void CustomHandlerDAO::unregisterContentHandler(const DPL::String& target, + const DPL::String& url) +{ + LogDebug("Removing content handler " << target << " " << url); + Try { + CUSTOM_HANDLER_DB_DELETE(deleteFrom, ContentHandlers); + deleteFrom->Where(And(Equals(m_pkgName), + And(Equals(target), + Equals(url)))); + deleteFrom->Execute(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAO::Exception::DatabaseError, + "Failed to remove content handler"); + } +} + +void CustomHandlerDAO::unregisterProtocolHandler(const DPL::String& target, + const DPL::String& url) +{ + LogDebug("Removing protocol handler " << target << " " << url); + Try { + CUSTOM_HANDLER_DB_DELETE(deleteFrom, ProtocolHandlers); + deleteFrom->Where(And(Equals(m_pkgName), + And(Equals(target), + Equals(url)))); + deleteFrom->Execute(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAO::Exception::DatabaseError, + "Failed to remove content handler"); + } +} + +void CustomHandlerDAO::unregisterContentHandler(const DPL::String& target, + const DPL::String& url, + const DPL::String& baseURL) +{ + LogDebug("Removing content handler " << target << " " << url); + Try { + CUSTOM_HANDLER_DB_DELETE(deleteFrom, ContentHandlers); + deleteFrom->Where(And(Equals(m_pkgName), + And(Equals(target), + And(Equals(url), + Equals(baseURL))))); + deleteFrom->Execute(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAO::Exception::DatabaseError, + "Failed to remove content handler"); + } +} + +void CustomHandlerDAO::unregisterProtocolHandler(const DPL::String& target, + const DPL::String& url, + const DPL::String& baseURL) +{ + LogDebug("Removing protocol handler " << target << " " << url); + Try { + CUSTOM_HANDLER_DB_DELETE(deleteFrom, ProtocolHandlers); + deleteFrom->Where(And(Equals(m_pkgName), + And(Equals(target), + And(Equals(url), + Equals( + baseURL))))); + deleteFrom->Execute(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAO::Exception::DatabaseError, + "Failed to remove content handler"); + } +} + +void CustomHandlerDAO::removeWidgetProtocolHandlers() +{ + LogDebug("ente"); + Try { + CUSTOM_HANDLER_DB_DELETE(deleteProtocol, ProtocolHandlers); + deleteProtocol->Where(Equals(m_pkgName)); + deleteProtocol->Execute(); + } Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAO::Exception::DatabaseError, + "Failed to remove widget protoc"); + } +} + +void CustomHandlerDAO::removeWidgetContentHandlers() +{ + LogDebug("ente"); + Try { + CUSTOM_HANDLER_DB_DELETE(deleteContent, ContentHandlers); + deleteContent->Where(Equals(m_pkgName)); + deleteContent->Execute(); + } Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAO::Exception::DatabaseError, + "Failed to remove widget entries"); + } +} +} // namespace CustomHandlerDB diff --git a/modules/custom_handler_dao/dao/custom_handler_dao_read_only.cpp b/modules/custom_handler_dao/dao/custom_handler_dao_read_only.cpp new file mode 100644 index 0000000..fd88c12 --- /dev/null +++ b/modules/custom_handler_dao/dao/custom_handler_dao_read_only.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of custom handler dao class. + * + * @file custom_handler_dao_read_only.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of custom handler dao + */ + +#include +#include + +#include + +using namespace DPL::DB::ORM; +using namespace DPL::DB::ORM::custom_handler; + +namespace CustomHandlerDB { +namespace { +template +CustomHandlerPtr getSingleHandler(std::list row) +{ + CustomHandlerPtr handler; + if (!row.empty()) { + // There should be only one + if (row.size() > 1) { + ThrowMsg(CustomHandlerDAOReadOnly::Exception::DatabaseError, + "More than one handler registered"); + } + + handler.reset(new CustomHandler()); + handler->target = row.front().Get_target(); + handler->base_url = row.front().Get_base_url(); + handler->url = row.front().Get_url(); + handler->title = row.front().Get_title(); + handler->user_decision = + static_cast(row.front().Get_user_allowed()); + } + return handler; +} +} // namespace + +CustomHandlerDAOReadOnly::CustomHandlerDAOReadOnly(const DPL::String& pkgName) + : + m_pkgName(pkgName) +{} + +CustomHandlerDAOReadOnly::~CustomHandlerDAOReadOnly() +{} + +CustomHandlerPtr CustomHandlerDAOReadOnly::getProtocolHandler( + const DPL::String& protocol, + const DPL::String& url) +{ + LogDebug("Getting protocol handler"); + Try { + CUSTOM_HANDLER_DB_SELECT(select, ProtocolHandlers); + + select->Where(And(Equals(m_pkgName), + And(Equals(protocol), + Equals(url)))); + + std::list list = select->GetRowList(); + return getSingleHandler(list); + } Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAOReadOnly::Exception::DatabaseError, + "Failed to get protocol handler"); + } +} + +CustomHandlerPtr CustomHandlerDAOReadOnly::getContentHandler( + const DPL::String& content, + const DPL::String& url) +{ + LogDebug("Getting content handler"); + Try { + CUSTOM_HANDLER_DB_SELECT(select, ContentHandlers); + + select->Where(And(Equals(m_pkgName), + And(Equals(content), + Equals(url)))); + + std::list list = select->GetRowList(); + return getSingleHandler(list); + } Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAOReadOnly::Exception::DatabaseError, + "Failed to get content handler"); + } +} + +CustomHandlerPtr CustomHandlerDAOReadOnly::getActivProtocolHandler( + const DPL::String& protocol) +{ + LogDebug("Getting active protocol handler"); + Try { + CUSTOM_HANDLER_DB_SELECT(select, ProtocolHandlers); + + select->Where(And(Equals(m_pkgName), + Equals(protocol))); + + std::list list = select->GetRowList(); + CustomHandlerPtr handler; + + FOREACH(it, list) { + if (it->Get_user_allowed() & Agreed) { + handler.reset(new CustomHandler()); + handler->base_url = it->Get_base_url(); + handler->target = it->Get_target(); + handler->title = it->Get_title(); + handler->url = it->Get_url(); + handler->user_decision = + static_cast(it->Get_user_allowed()); + } + } + return handler; + } Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAOReadOnly::Exception::DatabaseError, + "Failed to get protocol handler"); + } +} + +CustomHandlerPtr CustomHandlerDAOReadOnly::getProtocolHandler( + const DPL::String& protocol, + const DPL::String& url, + const DPL::String& baseURL) +{ + LogDebug("Check if protocol is registered"); + Try { + CUSTOM_HANDLER_DB_SELECT(select, ProtocolHandlers); + + select->Where(And(Equals(m_pkgName), + And(Equals(protocol), + And(Equals(url), + Equals(baseURL) + ) + ) + ) + ); + + std::list list = select->GetRowList(); + return getSingleHandler(list); + } Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAOReadOnly::Exception::DatabaseError, + "Failed to get content handler"); + } +} + +CustomHandlerPtr CustomHandlerDAOReadOnly::getActivContentHandler( + const DPL::String& content) +{ + LogDebug("Getting active content handler"); + Try { + CUSTOM_HANDLER_DB_SELECT(select, ContentHandlers); + + select->Where(And(Equals(m_pkgName), + Equals(content))); + + std::list list = select->GetRowList(); + CustomHandlerPtr handler; + + FOREACH(it, list) { + if (it->Get_user_allowed() & Agreed) { + handler.reset(new CustomHandler()); + handler->base_url = it->Get_base_url(); + handler->target = it->Get_target(); + handler->title = it->Get_title(); + handler->url = it->Get_url(); + handler->user_decision = + static_cast(it->Get_user_allowed()); + } + } + return handler; + } Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAOReadOnly::Exception::DatabaseError, + "Failed to get protocol handler"); + } +} + +CustomHandlerPtr CustomHandlerDAOReadOnly::getContentHandler( + const DPL::String& content, + const DPL::String& url, + const DPL::String& baseURL) +{ + LogDebug("Check if content is registered"); + Try { + CUSTOM_HANDLER_DB_SELECT(select, ContentHandlers); + + select->Where(And(Equals(m_pkgName), + And(Equals(content), + And(Equals(url), + Equals(baseURL))))); + + std::list list = select->GetRowList(); + return getSingleHandler(list); + } Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(CustomHandlerDAOReadOnly::Exception::DatabaseError, + "Failed to get content handler"); + } +} +} // namespace CustomHandlerDB diff --git a/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h b/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h new file mode 100644 index 0000000..4eabd55 --- /dev/null +++ b/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CUSTOM_HANDLER_DATABASE_H_ +#define _CUSTOM_HANDLER_DATABASE_H_ + +#include +#include +#include + +namespace CustomHandlerDB { +namespace Interface { +void attachDatabaseRO(); +void attachDatabaseRW(); +void detachDatabase(); + +extern DPL::Mutex g_dbQueriesMutex; +extern DPL::DB::ThreadDatabaseSupport g_dbInterface; +} // namespace Interface +} // namespace CustomHandlerDB + +#define CUSTOM_HANDLER_DB_INTERNAL(tlsCommand, InternalType) \ + static DPL::ThreadLocalVariable *tlsCommand##Ptr = NULL; \ + { \ + DPL::Mutex::ScopedLock lock( \ + &CustomHandlerDB::Interface::g_dbQueriesMutex); \ + if (!tlsCommand##Ptr) { \ + static DPL::ThreadLocalVariable tmp; \ + tlsCommand##Ptr = &tmp; \ + } \ + } \ + DPL::ThreadLocalVariable &tlsCommand = *tlsCommand##Ptr; \ + if (tlsCommand.IsNull()) \ + { \ + tlsCommand = InternalType(&CustomHandlerDB::Interface::g_dbInterface); \ + } + +#define CUSTOM_HANDLER_DB_SELECT(name, type) \ + CUSTOM_HANDLER_DB_INTERNAL(name, type::Select) + +#define CUSTOM_HANDLER_DB_INSERT(name, type) \ + CUSTOM_HANDLER_DB_INTERNAL(name, type::Insert) + +#define CUSTOM_HANDLER_DB_UPDATE(name, type) \ + CUSTOM_HANDLER_DB_INTERNAL(name, type::Update) + +#define CUSTOM_HANDLER_DB_DELETE(name, type) \ + CUSTOM_HANDLER_DB_INTERNAL(name, type::Delete) + +#endif /* _CUSTOM_HANDLER_DATABASE_H_ */ + diff --git a/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/common_dao_types.h b/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/common_dao_types.h new file mode 100644 index 0000000..e5a59f0 --- /dev/null +++ b/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/common_dao_types.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file common_dao_types.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of + * common data types for custom handler database. + */ +#ifndef SRC_MODULES_CUSTOM_HANDLERS_DAO_COMMON_DAO_TYPES_H_ +#define SRC_MODULES_CUSTOM_HANDLERS_DAO_COMMON_DAO_TYPES_H_ + +#include +#include +#include + +namespace CustomHandlerDB { +/** + * @brief Custom Handler struct + * + * Describes custom handler for protocol and content. + */ +enum HandlerState { + Agreed = 0x01, //user agreed to use protocol only, + //but want to ask in next occurence + Declined = 0x02, //user declined to use protocol, + //but want to ask in next occurence + //in fact it is used when user wants to cover saved + // agreed + //decision by agreeing to another one without save. + DecisionSaved = 0x04, //user dont want to ask again + AgreedPermanently = Agreed | DecisionSaved, + DeclinedPermanently = Declined | DecisionSaved +}; + +struct CustomHandler +{ + DPL::String target; // protocol/content ("mailto"/"application/x-soup") + DPL::String base_url; // base url of registered page + DPL::String url; // url used for protocol/content handling + DPL::String title; // user friendly handler name + HandlerState user_decision; +}; + +typedef std::shared_ptr CustomHandlerPtr; +typedef std::list CustomHandlersList; +} // namespace CustomHandlerDB + +#endif /* SRC_MODULES_CUSTOM_HANDLERS_DAO_COMMON_DAO_TYPES_H_ */ diff --git a/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h b/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h new file mode 100644 index 0000000..8ad4979 --- /dev/null +++ b/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of custom handler dao class. + * + * @file custom_handler_dao_read_only.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of custom handler dao + */ + +#ifndef _CUSTOM_HANDLER_DAO_READ_ONLY_H_ +#define _CUSTOM_HANDLER_DAO_READ_ONLY_H_ + +#include +#include +#include "common_dao_types.h" + +namespace CustomHandlerDB { +class CustomHandlerDAOReadOnly +{ + public: + /** + * CustomHandlerDAOReadOnly Exception classes + */ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DatabaseError) + }; + + public: + explicit CustomHandlerDAOReadOnly(const DPL::String& pkgName); + virtual ~CustomHandlerDAOReadOnly(); + + /** + * Returns protocol handler + */ + CustomHandlerPtr getProtocolHandler(const DPL::String& protocol, + const DPL::String& url); + CustomHandlerPtr getProtocolHandler(const DPL::String& protocol, + const DPL::String& url, + const DPL::String& baseURL); + + /** + * Returns protocol handler that is agreed or agreed and saved and match + * tizenID + */ + CustomHandlerPtr getActivProtocolHandler(const DPL::String& protocol); + + /** + * Returns content handler + */ + CustomHandlerPtr getContentHandler(const DPL::String& content, + const DPL::String& url); + CustomHandlerPtr getContentHandler(const DPL::String& protocol, + const DPL::String& url, + const DPL::String& baseURL); + + /** + * Returns content handler that is agreed or agreed and saved and match + * tizenID + */ + CustomHandlerPtr getActivContentHandler(const DPL::String& content); + + protected: + DPL::String m_pkgName; +}; +} // namespace CustomHandlerDB + +#endif // _CUSTOM_HANDLER_DAO_READ_ONLY_H_ + diff --git a/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-rw/custom_handler_dao.h b/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-rw/custom_handler_dao.h new file mode 100644 index 0000000..9a478cb --- /dev/null +++ b/modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-rw/custom_handler_dao.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of custom handler dao class. + * + * @file custom_handler_dao.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of custom handler dao + */ +#ifndef _CUSTOM_HANDLER_DAO_H_ +#define _CUSTOM_HANDLER_DAO_H_ + +#include + +namespace CustomHandlerDB { +class CustomHandlerDAO : public CustomHandlerDAOReadOnly +{ + public: + explicit CustomHandlerDAO(const DPL::String& pkgName); + virtual ~CustomHandlerDAO(); + + /** + * Registers custom content handler + */ + void registerContentHandler(const CustomHandler& handler); + + /** + * Registers custom protocol handler + */ + void registerProtocolHandler(const CustomHandler& handler); + + /** + * Unregisters custom content handler + */ + void unregisterContentHandler(const DPL::String& target, + const DPL::String& burl); + /** + * Unregisters custom protocol handler + */ + void unregisterProtocolHandler(const DPL::String& target, + const DPL::String& url); + + void unregisterContentHandler(const DPL::String& target, + const DPL::String& url, + const DPL::String& baseURL); + + void unregisterProtocolHandler(const DPL::String& target, + const DPL::String& url, + const DPL::String& baseURL); + + /** + * Removes all widget entries connected to given ID + */ + void removeWidgetProtocolHandlers(); + void removeWidgetContentHandlers(); +}; +} // namespace CustomHandlerDB + +#endif // _CUSTOM_HANDLER_DAO_H_ diff --git a/modules/custom_handler_dao/orm/custom_handler_db b/modules/custom_handler_dao/orm/custom_handler_db new file mode 100644 index 0000000..848c84a --- /dev/null +++ b/modules/custom_handler_dao/orm/custom_handler_db @@ -0,0 +1,34 @@ +SQL( + BEGIN TRANSACTION; +) + +CREATE_TABLE(ProtocolHandlers) + COLUMN_NOT_NULL(app_id, TEXT,) + COLUMN_NOT_NULL(target, TEXT,) + COLUMN_NOT_NULL(base_url, TEXT,) + COLUMN_NOT_NULL(url, TEXT,) + COLUMN_NOT_NULL(title, TEXT,) + COLUMN_NOT_NULL(user_allowed, INT,) + + TABLE_CONSTRAINTS( + PRIMARY KEY (app_id, target, base_url, url) + ) +CREATE_TABLE_END() + +CREATE_TABLE(ContentHandlers) + COLUMN_NOT_NULL(app_id, TEXT,) + COLUMN_NOT_NULL(target, TEXT,) + COLUMN_NOT_NULL(base_url, TEXT,) + COLUMN_NOT_NULL(url, TEXT,) + COLUMN_NOT_NULL(title, TEXT,) + COLUMN_NOT_NULL(user_allowed, INT,) + + TABLE_CONSTRAINTS( + PRIMARY KEY (app_id, target, base_url, url) + ) +CREATE_TABLE_END() + +SQL( + COMMIT; +) + diff --git a/modules/custom_handler_dao/orm/custom_handler_db_definitions b/modules/custom_handler_dao/orm/custom_handler_db_definitions new file mode 100644 index 0000000..1bc2bcd --- /dev/null +++ b/modules/custom_handler_dao/orm/custom_handler_db_definitions @@ -0,0 +1,6 @@ +DATABASE_START(custom_handler) + +#include "custom_handler_db" +#include "version_db" + +DATABASE_END() diff --git a/modules/custom_handler_dao/orm/custom_handler_db_sql_generator.h b/modules/custom_handler_dao/orm/custom_handler_db_sql_generator.h new file mode 100644 index 0000000..9b007de --- /dev/null +++ b/modules/custom_handler_dao/orm/custom_handler_db_sql_generator.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file custom_handler_db_sql_generator.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL + * input file from database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. +#include + +#include "custom_handler_db_definitions" diff --git a/modules/custom_handler_dao/orm/gen_db_md5.sh b/modules/custom_handler_dao/orm/gen_db_md5.sh new file mode 100755 index 0000000..22c2530 --- /dev/null +++ b/modules/custom_handler_dao/orm/gen_db_md5.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CHECKSUM=`cat ${2} ${3} 2>/dev/null | md5sum 2>/dev/null | cut -d\ -f1 2>/dev/null` +echo "#define DB_CHECKSUM DB_VERSION_${CHECKSUM}" > ${1} +echo "#define DB_CHECKSUM_STR \"DB_VERSION_${CHECKSUM}\"" >> ${1} + diff --git a/modules/custom_handler_dao/orm/orm_generator_custom_handler.h b/modules/custom_handler_dao/orm/orm_generator_custom_handler.h new file mode 100644 index 0000000..35c43a2 --- /dev/null +++ b/modules/custom_handler_dao/orm/orm_generator_custom_handler.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ORM_GENERATOR_CUSTOM_HANDLER_H_ +#define _ORM_GENERATOR_CUSTOM_HANDLER_H_ + +#define ORM_GENERATOR_DATABASE_NAME custom_handler_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif // _ORM_GENERATOR_CUSTOM_HANDLER_H_ diff --git a/modules/custom_handler_dao/orm/version_db b/modules/custom_handler_dao/orm/version_db new file mode 100644 index 0000000..7e20d8d --- /dev/null +++ b/modules/custom_handler_dao/orm/version_db @@ -0,0 +1,5 @@ +SQL( + BEGIN TRANSACTION; + CREATE TABLE DB_CHECKSUM (version INT); + COMMIT; +) diff --git a/modules/db/config.cmake b/modules/db/config.cmake new file mode 100644 index 0000000..96ccbb9 --- /dev/null +++ b/modules/db/config.cmake @@ -0,0 +1,45 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_DB_SOURCES + ${PROJECT_SOURCE_DIR}/modules/db/src/naive_synchronization_object.cpp + ${PROJECT_SOURCE_DIR}/modules/db/src/orm.cpp + ${PROJECT_SOURCE_DIR}/modules/db/src/sql_connection.cpp + ${PROJECT_SOURCE_DIR}/modules/db/src/thread_database_support.cpp + PARENT_SCOPE +) + + +SET(DPL_DB_HEADERS + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/naive_synchronization_object.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/orm_generator.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/orm.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/orm_interface.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/orm_macros.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/sql_connection.h + ${PROJECT_SOURCE_DIR}/modules/db/include/dpl/db/thread_database_support.h + PARENT_SCOPE +) + +SET(DPL_DB_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/db/include + PARENT_SCOPE +) diff --git a/modules/db/include/dpl/db/naive_synchronization_object.h b/modules/db/include/dpl/db/naive_synchronization_object.h new file mode 100644 index 0000000..2f63a0f --- /dev/null +++ b/modules/db/include/dpl/db/naive_synchronization_object.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file naive_synchronization_object.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of SQL naive + * synchronization object + */ +#ifndef DPL_NAIVE_SYNCHRONIZATION_OBJECT_H +#define DPL_NAIVE_SYNCHRONIZATION_OBJECT_H + +#include + +namespace DPL { +namespace DB { +/** + * Naive synchronization object used to synchronize SQL connection + * to the same database across different threads and processes + */ +class NaiveSynchronizationObject : + public SqlConnection::SynchronizationObject +{ + public: + // [SqlConnection::SynchronizationObject] + virtual void Synchronize(); + virtual void NotifyAll(); +}; +} // namespace DB +} // namespace DPL + +#endif // DPL_NAIVE_SYNCHRONIZATION_OBJECT_H diff --git a/modules/db/include/dpl/db/orm.h b/modules/db/include/dpl/db/orm.h new file mode 100644 index 0000000..652e8e1 --- /dev/null +++ b/modules/db/include/dpl/db/orm.h @@ -0,0 +1,1116 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file orm.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief DPL-ORM: Object-relational mapping for sqlite database, written on top of DPL. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifndef DPL_ORM_H +#define DPL_ORM_H + +namespace DPL { +namespace DB { +namespace ORM { + +//TODO move to type utils +#define DPL_CHECK_TYPE_INSTANTIABILITY(type) \ + { \ + type _ignored_; \ + (void)_ignored_; \ + } + +#define DECLARE_COLUMN_TYPE_LIST() typedef DPL::TypeListDecl< +#define SELECTED_COLUMN(table_name, column_name) table_name::column_name, +#define DECLARE_COLUMN_TYPE_LIST_END(name) DPL::TypeListGuard>::Type name; + +typedef size_t ColumnIndex; +typedef size_t ArgumentIndex; +typedef DPL::Optional OptionalString; +typedef DPL::Optional OptionalInteger; +typedef DPL::DB::SqlConnection::DataCommand DataCommand; + +namespace RelationTypes { + extern const char Equal[]; + extern const char LessThan[]; + extern const char And[]; + extern const char Or[]; + extern const char Is[]; + extern const char In[]; + //TODO define more relation types +} + +namespace DataCommandUtils { + //TODO move to DPL::DataCommand? + void BindArgument(DataCommand *command, ArgumentIndex index, int argument); + void BindArgument(DataCommand *command, ArgumentIndex index, const OptionalInteger& argument); + void BindArgument(DataCommand *command, ArgumentIndex index, const DPL::String& argument); + void BindArgument(DataCommand *command, ArgumentIndex index, const OptionalString& argument); +} +class __attribute__ ((visibility("hidden"))) Expression { +public: + virtual ~Expression() {} + virtual std::string GetString() const = 0; + virtual ArgumentIndex BindTo(DataCommand *command, ArgumentIndex index) = 0; +}; + +typedef std::shared_ptr ExpressionPtr; + +namespace OrderingUtils { + +template inline std::string OrderByInternal() +{ + std::string order = OrderByInternal(); + if(!order.empty()) return CompoundType::Head::GetString() + ", " + order; + else return CompoundType::Head::GetString(); +} + +template<> inline std::string OrderByInternal() +{ + return std::string(); +} + +} + +template +class __attribute__ ((visibility("hidden"))) OrderingExpression { +protected: + static std::string GetSchemaAndName() + { + std::string statement; + statement += ColumnType::GetTableName(); + statement += "."; + statement += ColumnType::GetColumnName(); + statement += " "; + return statement; + } +public: + virtual ~OrderingExpression() {} +}; + +template +class __attribute__ ((visibility("hidden"))) BinaryExpression : public Expression { +protected: + LeftExpression m_leftExpression; + RightExpression m_rightExpression; + bool m_outerParenthesis; +public: + BinaryExpression(const LeftExpression& leftExpression, const RightExpression& rightExpression, bool outerParenthesis = true) : + m_leftExpression(leftExpression), + m_rightExpression(rightExpression), + m_outerParenthesis(outerParenthesis) + {} + + virtual std::string GetString() const + { + return (m_outerParenthesis ? "( " : " " ) + + m_leftExpression.GetString() + " " + Operator + " " + m_rightExpression.GetString() + + (m_outerParenthesis ? " )" : " " ) ; + } + + virtual ArgumentIndex BindTo(DataCommand *command, ArgumentIndex index) + { + index = m_leftExpression.BindTo(command, index); + return m_rightExpression.BindTo(command, index); + } + + template + struct ValidForTable { + typedef std::pair::Yes , + typename RightExpression::template ValidForTable::Yes > + Yes; + }; +}; + +template +BinaryExpression + And(const LeftExpression& leftExpression, const RightExpression& rightExpression) +{ + return BinaryExpression + (leftExpression, rightExpression); +} + +template +BinaryExpression + Or(const LeftExpression& leftExpression, const RightExpression& rightExpression) +{ + return BinaryExpression + (leftExpression, rightExpression); +} + +template +class __attribute__ ((visibility("hidden"))) ExpressionWithArgument : public Expression { +protected: + ArgumentType argument; + +public: + explicit ExpressionWithArgument(const ArgumentType& _argument) : argument(_argument) {} + + virtual ArgumentIndex BindTo(DataCommand *command, ArgumentIndex index) + { + DataCommandUtils::BindArgument(command, index, argument); + return index + 1; + } +}; + +template +class __attribute__ ((visibility("hidden"))) Compare : public ExpressionWithArgument { +public: + explicit Compare(typename ColumnData::ColumnType column) : + ExpressionWithArgument(column) + {} + + virtual std::string GetString() const + { + std::string statement; + statement += ColumnData::GetTableName(); + statement += "."; + statement += ColumnData::GetColumnName(); + statement += " "; + statement += Relation; + statement += " ?"; + return statement; + } + + template + struct ValidForTable { + typedef typename TableDefinition::ColumnList::template Contains Yes; + }; +}; +#define ORM_DEFINE_COMPARE_EXPRESSION(name, relationType) \ + template \ + class __attribute__ ((visibility("hidden"))) name : public Compare { \ + public: \ + name(typename ColumnData::ColumnType column) : \ + Compare(column) \ + {} \ + }; + +ORM_DEFINE_COMPARE_EXPRESSION(Equals, Equal) +ORM_DEFINE_COMPARE_EXPRESSION(Is, Is) + +#define ORM_DEFINE_ORDERING_EXPRESSION(name, value) \ + template \ + class __attribute__ ((visibility("hidden"))) name \ + : OrderingExpression { \ + public: \ + static std::string GetString() \ + { \ + std::string statement = OrderingExpression::GetSchemaAndName(); \ + statement += value; \ + return statement; \ + } \ + }; + +ORM_DEFINE_ORDERING_EXPRESSION(OrderingAscending, "ASC") +ORM_DEFINE_ORDERING_EXPRESSION(OrderingDescending, "DESC") + +template +class __attribute__ ((visibility("hidden"))) CompareBinaryColumn { +private: + std::string m_relation; +public: + CompareBinaryColumn(const char* Relation) : + m_relation(Relation) + {} + + virtual ~CompareBinaryColumn() {} + + virtual std::string GetString() const + { + std::string statement; + statement += ColumnData1::GetTableName(); + statement += "."; + statement += ColumnData1::GetColumnName(); + statement += " "; + statement += m_relation; + statement += " "; + statement += ColumnData2::GetTableName(); + statement += "."; + statement += ColumnData2::GetColumnName(); + + return statement; + } +}; + +template +CompareBinaryColumn + Equal() +{ + return CompareBinaryColumn(RelationTypes::Equal); +} + +template +class __attribute__ ((visibility("hidden"))) NumerousArguments : public Expression { +protected: + std::set m_argumentList; +public: + NumerousArguments(const std::set& argumentList) : m_argumentList(argumentList) {} + + virtual std::string GetString() const + { + std::string statement; + statement += ColumnData::GetColumnName(); + statement += " "; + statement += Relation; + statement += " ( "; + + int argumentCount = m_argumentList.size(); + while(argumentCount) + { + statement += "?"; + argumentCount--; + if (argumentCount) + { + statement += ", "; + } + } + + statement += " )"; + + return statement; + } + + virtual ArgumentIndex BindTo(DataCommand *command, ArgumentIndex index) + { + ArgumentIndex argumentIndex = index; + FOREACH(argumentIt, m_argumentList) + { + DataCommandUtils::BindArgument(command, argumentIndex, *argumentIt); + argumentIndex++; + } + return argumentIndex + 1; + } + + template + struct ValidForTable { + typedef typename TableDefinition::ColumnList::template Contains Yes; + }; +}; + +#define ORM_DEFINE_COMPARE_EXPRESSION_NUMEROUS_ARGUMENTS(name, relationType) \ + template \ + class __attribute__ ((visibility("hidden"))) name : public NumerousArguments { \ + public: \ + name(std::set column) : \ + NumerousArguments(column) \ + {} \ + }; + +ORM_DEFINE_COMPARE_EXPRESSION_NUMEROUS_ARGUMENTS(In, In) + +template +ColumnType GetColumnFromCommand(ColumnIndex columnIndex, DataCommand *command); + +class __attribute__ ((visibility("hidden"))) CustomColumnBase { +public: + CustomColumnBase() {} + virtual ~CustomColumnBase() {} +}; + +template +class __attribute__ ((visibility("hidden"))) CustomColumn : public CustomColumnBase { +private: + ColumnType m_columnData; + +public: + CustomColumn() {} + CustomColumn(ColumnType data) + { + m_columnData = data; + } + + void SetColumnData(ColumnType data) + { + m_columnData = data; + } + + ColumnType GetColumnData() const + { + return m_columnData; + } +}; + +template +class __attribute__ ((visibility("hidden"))) CustomRowUtil { +public: + static void MakeColumnList(std::vector& columnList) + { + typedef CustomColumn Type; + Type* pColumn = new Type(); + columnList.push_back(pColumn); + CustomRowUtil::MakeColumnList(columnList); + } + + static void CopyColumnList(const std::vector& srcList, std::vector& dstList) + { + CopyColumnList(srcList, dstList, 0); + } + + static ColumnIndex GetColumnIndex(const std::string& columnName) + { + return GetColumnIndex(columnName, 0); + } + +private: + static void CopyColumnList(const std::vector& srcList, std::vector& dstList, ColumnIndex index) + { + typedef CustomColumn Type; + Type* pColumn = new Type(((Type*)(srcList.at(index)))->GetColumnData()); + dstList.push_back(pColumn); + CustomRowUtil::CopyColumnList(srcList, dstList, index + 1); + } + + static ColumnIndex GetColumnIndex(const std::string& columnName, ColumnIndex index) + { + if (ColumnList::Head::GetColumnName() == columnName) + return index; + + return CustomRowUtil::GetColumnIndex(columnName, index + 1); + } + +template +friend class CustomRowUtil; +}; + +template<> +class __attribute__ ((visibility("hidden"))) CustomRowUtil { +public: + static void MakeColumnList(std::vector&) {} +private: + static void CopyColumnList(const std::vector&, std::vector&, ColumnIndex) {} + static ColumnIndex GetColumnIndex(const std::string&, ColumnIndex) { return -1; } + +template +friend class CustomRowUtil; +}; + +template +class __attribute__ ((visibility("hidden"))) CustomRow { +private: + std::vector m_columns; + +public: + CustomRow() + { + CustomRowUtil::MakeColumnList(m_columns); + } + + CustomRow(const CustomRow& r) + { + CustomRowUtil::CopyColumnList(r.m_columns, m_columns); + } + + virtual ~CustomRow() + { + while (!m_columns.empty()) + { + CustomColumnBase* pCustomColumn = m_columns.back(); + m_columns.pop_back(); + if (pCustomColumn) + delete pCustomColumn; + } + } + + template + void SetColumnData(ColumnIndex columnIndex, ColumnType data) + { + typedef CustomColumn Type; + Assert(columnIndex < m_columns.size()); + Type* pColumn = dynamic_cast(m_columns.at(columnIndex)); + Assert(pColumn); + pColumn->SetColumnData(data); + } + + template + typename ColumnData::ColumnType GetColumnData() + { + typedef CustomColumn Type; + ColumnIndex index = CustomRowUtil::GetColumnIndex(ColumnData::GetColumnName()); + Assert(index < m_columns.size()); + Type* pColumn = dynamic_cast(m_columns.at(index)); + Assert(pColumn); + return pColumn->GetColumnData(); + } +}; + +template +void SetColumnData(CustomRow& row, ColumnType columnData, ColumnIndex columnIndex) +{ + row.SetColumnData(columnIndex, columnData); +} + +template +class __attribute__ ((visibility("hidden"))) FillCustomRowUtil { +public: + static void FillCustomRow(CustomRow& row, DataCommand* command) + { + FillCustomRow(row, 0, command); + } + +private: + static void FillCustomRow(CustomRow& row, ColumnIndex columnIndex, DataCommand* command) + { + typename ColumnList::Head::ColumnType columnData; + columnData = GetColumnFromCommand(columnIndex, command); + SetColumnData(row, columnData, columnIndex); + FillCustomRowUtil::FillCustomRow(row, columnIndex + 1, command); + } + +template +friend class FillCustomRowUtil; +}; + +template +class __attribute__ ((visibility("hidden"))) FillCustomRowUtil { +private: + static void FillCustomRow(CustomRow&, ColumnIndex, DataCommand *) + { /* do nothing, we're past the last element of column list */ } + +template +friend class FillCustomRowUtil; +}; + +template +class __attribute__ ((visibility("hidden"))) FillRowUtil { +public: + static void FillRow(Row& row, DataCommand *command) + { + FillRow(row, 0, command); + } + +private: + static void FillRow(Row& row, ColumnIndex columnIndex, DataCommand *command) + { + typename ColumnList::Head::ColumnType rowField; + rowField = GetColumnFromCommand(columnIndex, command); + ColumnList::Head::SetRowField(row, rowField); + FillRowUtil::FillRow(row, columnIndex + 1, command); + } + +template +friend class FillRowUtil; +}; + +template +class __attribute__ ((visibility("hidden"))) FillRowUtil { +private: + static void FillRow(Row&, ColumnIndex, DataCommand *) + { /* do nothing, we're past the last element of column list */ } + +template +friend class FillRowUtil; +}; + +template +class __attribute__ ((visibility("hidden"))) JoinUtil { +public: + static std::string GetColumnNames() + { + std::string result; + result = ColumnList::Head::GetTableName(); + result += "."; + result += ColumnList::Head::GetColumnName(); + if (ColumnList::Tail::Size > 0) + result += ", "; + + return result += JoinUtil::GetColumnNames(); + } + + static std::string GetJoinTableName(const std::string& tableName) + { + std::string joinTableName = ColumnList::Head::GetTableName(); + if (tableName.find(joinTableName) == std::string::npos) + return joinTableName; + + return JoinUtil::GetJoinTableName(tableName); + } +}; + +template<> +class __attribute__ ((visibility("hidden"))) JoinUtil { +public: + static std::string GetColumnNames() { return ""; } + static std::string GetJoinTableName(std::string) { return ""; } +}; + +class Exception { +public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, SelectReuseWithDifferentQuerySignature) + DECLARE_EXCEPTION_TYPE(Base, RowFieldNotInitialized) + DECLARE_EXCEPTION_TYPE(Base, EmptyUpdateStatement) +}; + +template +class __attribute__ ((visibility("hidden"))) Query +{ +protected: + explicit Query(IOrmInterface* interface) : + m_interface(interface), + m_command(NULL) + { + } + + virtual ~Query() + { + if (m_command == NULL) + return; + + TableDefinition::FreeTableDataCommand(m_command, m_interface); + } + + IOrmInterface* m_interface; + DataCommand *m_command; + std::string m_commandString; + ArgumentIndex m_bindArgumentIndex; +}; + +template +class __attribute__ ((visibility("hidden"))) QueryWithWhereClause : public Query +{ +protected: + ExpressionPtr m_whereExpression; + + void Prepare() + { + if ( !!m_whereExpression ) + { + this->m_commandString += " WHERE "; + this->m_commandString += m_whereExpression->GetString(); + } + } + + void Bind() + { + if ( !!m_whereExpression ) + { + this->m_bindArgumentIndex = m_whereExpression->BindTo( + this->m_command, this->m_bindArgumentIndex); + } + } + +public: + explicit QueryWithWhereClause(IOrmInterface* interface) : + Query(interface) + { + } + + template + void Where(const Expression& expression) + { + DPL_CHECK_TYPE_INSTANTIABILITY(typename Expression::template ValidForTable::Yes); + if ( !!m_whereExpression && ( typeid(Expression) != typeid(*m_whereExpression) ) ) + { + std::ostringstream str; + str << "Current ORM implementation doesn't allow to reuse Select" + " instance with different query signature (particularly " + "WHERE on different column).\n"; + str << "Query: "; + str << this->m_commandString; + ThrowMsg(Exception::SelectReuseWithDifferentQuerySignature, + str.str()); + } + //TODO maybe don't make a copy here but just generate the string part of the query. + m_whereExpression.reset(new Expression(expression)); + } + +}; + +template +class __attribute__ ((visibility("hidden"))) Delete : public QueryWithWhereClause +{ +protected: + void Prepare() + { + if ( !this->m_command) + { + this->m_commandString = "DELETE FROM "; + this->m_commandString += TableDefinition::GetName(); + + QueryWithWhereClause::Prepare(); + + this->m_command = TableDefinition::AllocTableDataCommand( + this->m_commandString.c_str(), + Query::m_interface); + LogPedantic("Prepared SQL command " << this->m_commandString); + } + } + + void Bind() + { + this->m_bindArgumentIndex = 1; + QueryWithWhereClause::Bind(); + } + +public: + explicit Delete(IOrmInterface *interface = NULL) : + QueryWithWhereClause(interface) + { + } + + void Execute() + { + Prepare(); + Bind(); + this->m_command->Step(); + this->m_command->Reset(); + } +}; + +namespace { +class BindVisitor { +private: + DataCommand *m_command; +public: + ArgumentIndex m_bindArgumentIndex; + + BindVisitor(DataCommand *command) : + m_command(command), + m_bindArgumentIndex(1) + {} + + template + void Visit(const char*, const ColumnType& value, bool isSet) + { + if ( isSet ) + { + DataCommandUtils::BindArgument(m_command, m_bindArgumentIndex, value); + m_bindArgumentIndex++; + } + } +}; +} //anonymous namespace +template +class __attribute__ ((visibility("hidden"))) Insert : public Query +{ +public: + typedef typename TableDefinition::Row Row; + typedef DPL::DB::SqlConnection::RowID RowID; + +protected: + DPL::Optional m_orClause; + Row m_row; + + class PrepareVisitor { + public: + std::string m_columnNames; + std::string m_values; + + template + void Visit(const char* name, const ColumnType&, bool isSet) + { + if ( isSet ) + { + if ( !m_columnNames.empty() ) + { + m_columnNames += ", "; + m_values += ", "; + } + m_columnNames += name; + m_values += "?"; + } + } + }; + + void Prepare() + { + if ( !this->m_command ) + { + this->m_commandString = "INSERT "; + if ( !!m_orClause ) + { + this->m_commandString += " OR " + *m_orClause + " "; + } + this->m_commandString += "INTO "; + this->m_commandString += TableDefinition::GetName(); + + PrepareVisitor visitor; + m_row.VisitColumns(visitor); + + this->m_commandString += " ( " + visitor.m_columnNames + " ) "; + this->m_commandString += "VALUES ( " + visitor.m_values + " )"; + + LogPedantic("Prepared SQL command " << this->m_commandString); + this->m_command = TableDefinition::AllocTableDataCommand( + this->m_commandString.c_str(), + Query::m_interface); + } + } + + void Bind() + { + BindVisitor visitor(this->m_command); + m_row.VisitColumns(visitor); + } + +public: + explicit Insert( + IOrmInterface* interface = NULL, + const DPL::Optional& orClause = DPL::Optional::Null) : + Query(interface), + m_orClause(orClause) + { + } + + void Values(const Row& row) + { + if ( this->m_command ) + { + if ( !row.IsSignatureMatching(m_row) ) + { + ThrowMsg(Exception::SelectReuseWithDifferentQuerySignature, + "Current ORM implementation doesn't allow to reuse Insert instance " + "with different query signature."); + } + } + m_row = row; + } + + RowID Execute() + { + Prepare(); + Bind(); + this->m_command->Step(); + + RowID result = TableDefinition::GetLastInsertRowID( + Query::m_interface); + + this->m_command->Reset(); + return result; + } +}; + +template +class __attribute__ ((visibility("hidden"))) Select : public QueryWithWhereClause +{ +public: + typedef typename TableDefinition::ColumnList ColumnList; + typedef typename TableDefinition::Row Row; + + typedef std::list RowList; +protected: + DPL::Optional m_orderBy; + std::string m_JoinClause; + bool m_distinctResults; + + void Prepare(const char* selectColumnName) + { + if ( !this->m_command ) + { + this->m_commandString = "SELECT "; + if (m_distinctResults) + this->m_commandString += "DISTINCT "; + this->m_commandString += selectColumnName; + this->m_commandString += " FROM "; + this->m_commandString += TableDefinition::GetName(); + + this->m_commandString += m_JoinClause; + + QueryWithWhereClause::Prepare(); + + if ( !m_orderBy.IsNull() ) + { + this->m_commandString += " ORDER BY " + *m_orderBy; + } + + this->m_command = TableDefinition::AllocTableDataCommand( + this->m_commandString.c_str(), + Query::m_interface); + + LogPedantic("Prepared SQL command " << this->m_commandString); + } + } + + void Bind() + { + this->m_bindArgumentIndex = 1; + QueryWithWhereClause::Bind(); + } + + template + ColumnType GetColumn(ColumnIndex columnIndex) + { + return GetColumnFromCommand(columnIndex, this->m_command); + } + + Row GetRow() + { + Row row; + FillRowUtil::FillRow(row, this->m_command); + return row; + } + + template + CustomRow GetCustomRow() + { + CustomRow row; + FillCustomRowUtil::FillCustomRow(row, this->m_command); + return row; + } + +public: + + explicit Select(IOrmInterface *interface = NULL) : + QueryWithWhereClause(interface), + m_distinctResults(false) + { + } + + void Distinct() + { + m_distinctResults = true; + } + + template + void OrderBy(const CompoundType&) + { + m_orderBy = OrderingUtils::OrderByInternal(); + } + + void OrderBy(const std::string & orderBy) //backward compatibility + { + m_orderBy = orderBy; + } + + void OrderBy(const char * orderBy) //backward compatibility + { + m_orderBy = std::string(orderBy); + } + + template + void Join(const Expression& expression) { + std::string usedTableNames = TableDefinition::GetName(); + if (!m_JoinClause.empty()) + usedTableNames += m_JoinClause; + + this->m_JoinClause += " JOIN "; + this->m_JoinClause += JoinUtil::GetJoinTableName(usedTableNames); + this->m_JoinClause += " ON "; + this->m_JoinClause += expression.GetString(); + } + + template + typename ColumnData::ColumnType GetSingleValue() + { + Prepare(ColumnData::GetColumnName()); + Bind(); + this->m_command->Step(); + + typename ColumnData::ColumnType result = + GetColumn(0); + + this->m_command->Reset(); + return result; + } + + //TODO return range - pair of custom iterators + template + std::list GetValueList() + { + Prepare(ColumnData::GetColumnName()); + Bind(); + + std::list resultList; + + while (this->m_command->Step()) + resultList.push_back(GetColumn(0)); + + this->m_command->Reset(); + return resultList; + } + + Row GetSingleRow() + { + Prepare("*"); + Bind(); + this->m_command->Step(); + + Row result = GetRow(); + + this->m_command->Reset(); + return result; + } + + //TODO return range - pair of custom iterators + RowList GetRowList() + { + Prepare("*"); + Bind(); + + RowList resultList; + + while (this->m_command->Step()) + resultList.push_back(GetRow()); + + this->m_command->Reset(); + return resultList; + } + + template + CustomRow GetCustomSingleRow() + { + Prepare(JoinUtil::GetColumnNames().c_str()); + Bind(); + this->m_command->Step(); + + CustomRow result = GetCustomRow(); + + this->m_command->Reset(); + return result; + } + + template + std::list GetCustomRowList() + { + Prepare(JoinUtil::GetColumnNames().c_str()); + Bind(); + + std::list resultList; + + while (this->m_command->Step()) + resultList.push_back(GetCustomRow()); + + this->m_command->Reset(); + return resultList; + } +}; + +template +class __attribute__ ((visibility("hidden"))) Update : public QueryWithWhereClause { +public: + typedef typename TableDefinition::Row Row; + +protected: + DPL::Optional m_orClause; + Row m_row; + + class PrepareVisitor { + public: + std::string m_setExpressions; + + template + void Visit(const char* name, const ColumnType&, bool isSet) + { + if ( isSet ) + { + if ( !m_setExpressions.empty() ) + { + m_setExpressions += ", "; + } + m_setExpressions += name; + m_setExpressions += " = "; + m_setExpressions += "?"; + } + } + }; + + void Prepare() + { + if ( !this->m_command ) + { + this->m_commandString = "UPDATE "; + if ( !!m_orClause ) + { + this->m_commandString += " OR " + *m_orClause + " "; + } + this->m_commandString += TableDefinition::GetName(); + this->m_commandString += " SET "; + + // got through row columns and values + PrepareVisitor visitor; + m_row.VisitColumns(visitor); + + if(visitor.m_setExpressions.empty()) + { + ThrowMsg(Exception::EmptyUpdateStatement, "No SET expressions in update statement"); + } + + this->m_commandString += visitor.m_setExpressions; + + // where + QueryWithWhereClause::Prepare(); + + this->m_command = TableDefinition::AllocTableDataCommand( + this->m_commandString.c_str(), + Query::m_interface); + LogPedantic("Prepared SQL command " << this->m_commandString); + } + } + + void Bind() + { + BindVisitor visitor(this->m_command); + m_row.VisitColumns(visitor); + + this->m_bindArgumentIndex = visitor.m_bindArgumentIndex; + QueryWithWhereClause::Bind(); + } + + +public: + explicit Update(IOrmInterface *interface = NULL, + const DPL::Optional& orClause = DPL::Optional::Null) : + QueryWithWhereClause(interface), + m_orClause(orClause) + { + } + + void Values(const Row& row) + { + if ( this->m_command ) + { + if ( !row.IsSignatureMatching(m_row) ) + { + ThrowMsg(Exception::SelectReuseWithDifferentQuerySignature, + "Current ORM implementation doesn't allow to reuse Update instance " + "with different query signature."); + } + } + m_row = row; + } + + void Execute() + { + Prepare(); + Bind(); + this->m_command->Step(); + this->m_command->Reset(); + } +}; + +} //namespace ORM +} //namespace DB +} //namespace DPL + +#endif // DPL_ORM_H diff --git a/modules/db/include/dpl/db/orm_generator.h b/modules/db/include/dpl/db/orm_generator.h new file mode 100644 index 0000000..8bd9fdb --- /dev/null +++ b/modules/db/include/dpl/db/orm_generator.h @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file orm_generator.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the DPL-ORM table definitions from database definitions. + */ + +#ifndef ORM_GENERATOR_DATABASE_NAME +#error You need to define database name in ORM_GENERATOR_DATABASE_NAME define before you include orm_generator.h file +#endif + +#include + +#define ORM_GENERATOR_DATABASE_NAME_LOCAL + +#ifdef DPL_ORM_GENERATOR_H +#warning orm_generator.h is included multiply times. Make sure it has different ORM_GENERATOR_DATABASE_NAME set. +#endif + +#define DPL_ORM_GENERATOR_H + + +#include +#include +#include +#include +#include +#include +#include + +/* + +This is true only when exactly one db is available. + +#if (defined DECLARE_COLUMN) || (defined INT) || (defined TINYINT) || \ + (defined INTEGER) || (defined BIGINT) || defined(VARCHAR) || defined(TEXT) || \ + (defined SQL) || (defined TABLE_CONSTRAINTS) || (defined OPTIONAL) || \ + (defined DATABASE_START) || (defined DATABASE_END) || (defined CREATE_TABLE) || \ + (defined COLUMN) || (defined COLUMN_NOT_NULL) || (defined CREATE_TABLE_END) + +#error This file temporarily defines many macros with generic names. To avoid name clash please include \ + this file as early as possible. If this is not possible please report this problem to DPL developers. + +#endif +*/ + +namespace DPL { +namespace DB { +namespace ORM { + +// Global macros + +#define STRINGIFY(s) _str(s) +#define _str(s) #s +#define DECLARE_COLUMN(FIELD, TYPE) \ + struct FIELD { \ + typedef TYPE ColumnType; \ + static const char* GetTableName() { return GetName(); } \ + static const char* GetColumnName() { return STRINGIFY(FIELD); } \ + static void SetRowField(Row& row, const TYPE& _value) { row.Set_##FIELD(_value);} \ + }; + +#define INT int +#define TINYINT int +#define INTEGER int //TODO: should be long long? +#define BIGINT int //TODO: should be long long? +#define VARCHAR(x) DPL::String +#define TEXT DPL::String + +#define SQL(...) +#define TABLE_CONSTRAINTS(...) +#define OPTIONAL(type) DPL::Optional< type > +#define DATABASE_START(db_name) \ + namespace db_name \ + { \ + class ScopedTransaction \ + { \ + bool m_commited; \ + IOrmInterface *m_interface; \ + \ + public: \ + ScopedTransaction(IOrmInterface *interface) : \ + m_commited(false), \ + m_interface(interface) \ + { \ + Assert(interface != NULL); \ + m_interface->TransactionBegin(); \ + } \ + \ + ~ScopedTransaction() \ + { \ + if (!m_commited) \ + m_interface->TransactionRollback(); \ + } \ + \ + void Commit() \ + { \ + m_interface->TransactionCommit(); \ + m_commited = true; \ + } \ + }; + +#define DATABASE_END() } + +// RowBase ostream operator<< declaration + +#define CREATE_TABLE(name) \ + namespace name { \ + class RowBase; \ + inline std::ostream& operator<<(std::ostream& ostr, const RowBase& row); \ + } +#define COLUMN_NOT_NULL(name, type, ...) +#define COLUMN(name, type, ...) +#define CREATE_TABLE_END() + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +#undef DATABASE_START +#define DATABASE_START(db_name) namespace db_name { + +// RowBase class + +#define CREATE_TABLE(name) namespace name { class RowBase { \ + public: friend std::ostream& operator<<(std::ostream&, const RowBase&); +#define COLUMN_NOT_NULL(name, type, ...) \ + protected: type name; bool m_##name##_set; \ + public: void Set_##name(const type& _value) { \ + m_##name##_set = true; \ + this->name = _value; \ + } \ + public: type Get_##name() const { \ + if ( !m_##name##_set ) { \ + ThrowMsg(Exception::RowFieldNotInitialized, \ + "You tried to read a row field that hasn't been set yet."); \ + } \ + return name; \ + } + +#define COLUMN(name, type, ...) \ + protected: OPTIONAL(type) name; bool m_##name##_set; \ + public: void Set_##name(const OPTIONAL(type)& _value) { \ + m_##name##_set = true; \ + this->name = _value; \ + } \ + public: OPTIONAL(type) Get_##name() const { \ + if ( !m_##name##_set ) { \ + ThrowMsg(Exception::RowFieldNotInitialized, \ + "You tried to read a row field that hasn't been set yet."); \ + } \ + return name; \ + } +#define CREATE_TABLE_END() }; } + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +// RowBase ostream operator<< + +#define CREATE_TABLE(name) std::ostream& name::operator<<(std::ostream& ostr, const RowBase& row) { using ::operator<< ; ostr << STRINGIFY(name) << " ("; +#define COLUMN_NOT_NULL(name, type, ...) ostr << " '" << row.name << "'" ; +#define COLUMN(name, type, ...) ostr << " '" << row.name << "'" ; +#define CREATE_TABLE_END() ostr << " )" ; return ostr; } + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +// RowBase2 class (== RowBase + operator==) + +#define CREATE_TABLE(name) namespace name { class RowBase2 : public RowBase { \ + public: bool operator==(const RowBase2& row) const { return true +#define COLUMN_NOT_NULL(name, type, ...) && (this->name == row.name) +#define COLUMN(name, type, ...) && (this->name == row.name) +#define CREATE_TABLE_END() ; } }; } + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +// RowBase3 class (== RowBase2 + operator<) + +#define CREATE_TABLE(name) namespace name { class RowBase3 : public RowBase2 { \ + public: bool operator<(const RowBase3& row) const { +#define COLUMN_NOT_NULL(name, type, ...) if (this->name < row.name) { return true; } if (this->name > row.name) { return false; } +#define COLUMN(name, type, ...) if (this->name < row.name) { return true; } if (this->name > row.name) { return false; } +#define CREATE_TABLE_END() return false; } }; } + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +// RowBase4 class (== RowBase3 + IsSignatureMatching ) + +#define CREATE_TABLE(name) namespace name { class RowBase4 : public RowBase3 { \ + public: bool IsSignatureMatching(const RowBase4& row) const { return true +#define COLUMN_NOT_NULL(name, type, ...) && (this->m_##name##_set == row.m_##name##_set) +#define COLUMN(name, type, ...) && (this->m_##name##_set == row.m_##name##_set) +#define CREATE_TABLE_END() ; } }; } + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +// RowBase5 class (== RowBase4 + default constructor) + +#define CREATE_TABLE(name) namespace name { class RowBase5 : public RowBase4 { \ + public: RowBase5() { +#define COLUMN_NOT_NULL(name, type, ...) m_##name##_set = false; +#define COLUMN(name, type, ...) m_##name##_set = false; +#define CREATE_TABLE_END() } }; } + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +// Row class (== RowBase5 + ForEachColumn ) + +#define CREATE_TABLE(name) namespace name { class Row : public RowBase5 { \ + public: template \ + void VisitColumns(Visitor& visitor) const { +#define COLUMN_NOT_NULL(name, type, ...) visitor.Visit(STRINGIFY(name), this->name, this->m_##name##_set); +#define COLUMN(name, type, ...) visitor.Visit(STRINGIFY(name), this->name, this->m_##name##_set); +#define CREATE_TABLE_END() } }; } + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +// Field structure declarations + +#define CREATE_TABLE(name) namespace name { \ + static const char* GetName() { return STRINGIFY(name); } +#define COLUMN_NOT_NULL(name, type, ...) DECLARE_COLUMN(name, type) +#define COLUMN(name, type, ...) DECLARE_COLUMN(name, OPTIONAL(type)) +#define CREATE_TABLE_END() } + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +// ColumnList typedef + +#define CREATE_TABLE(name) namespace name { typedef DPL::TypeListDecl< +#define COLUMN_NOT_NULL(name, type, ...) name, +#define COLUMN(name, type, ...) name, +#define CREATE_TABLE_END() DPL::TypeListGuard>::Type ColumnList; } + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +// TableDefinition struct + +#define CREATE_TABLE(table_name) \ + namespace table_name { \ + struct TableDefinition { \ + typedef table_name::ColumnList ColumnList; \ + typedef table_name::Row Row; \ + static const char* GetName() { return STRINGIFY(table_name); } \ + static DPL::DB::SqlConnection::DataCommand *AllocTableDataCommand( \ + const std::string &statement, \ + IOrmInterface *interface) \ + { \ + Assert(interface != NULL); \ + return interface->AllocDataCommand(statement); \ + } \ + static void FreeTableDataCommand( \ + DPL::DB::SqlConnection::DataCommand *command, \ + IOrmInterface *interface) \ + { \ + Assert(interface != NULL); \ + interface->FreeDataCommand(command); \ + } \ + static DPL::DB::SqlConnection::RowID GetLastInsertRowID( \ + IOrmInterface *interface) \ + { \ + Assert(interface != NULL); \ + return interface->GetLastInsertRowID(); \ + } \ + }; \ + } + +#define COLUMN_NOT_NULL(name, type, ...) +#define COLUMN(name, type, ...) +#define CREATE_TABLE_END() + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + +// Query typedefs + +#define CREATE_TABLE(name) \ + namespace name { \ + typedef Select Select; \ + typedef Insert Insert; \ + typedef Delete Delete; \ + typedef Update Update; \ + } +#define COLUMN_NOT_NULL(name, type, ...) +#define COLUMN(name, type, ...) +#define CREATE_TABLE_END() + +#include ORM_GENERATOR_DATABASE_NAME_LOCAL + +#undef CREATE_TABLE +#undef COLUMN_NOT_NULL +#undef COLUMN +#undef CREATE_TABLE_END + + +// Global undefs +#undef INT +#undef TINYINT +#undef INTEGER +#undef BIGINT +#undef VARCHAR +#undef TEXT + +#undef SQL +#undef TABLE_CONSTRAINTS +#undef OPTIONAL +#undef DATABASE_START +#undef DATABASE_END + +} //namespace ORM +} //namespace DB +} //namespace DPL + +#undef ORM_GENERATOR_DATABASE_NAME +#undef ORM_GENERATOR_DATABASE_NAME_LOCAL diff --git a/modules/db/include/dpl/db/orm_interface.h b/modules/db/include/dpl/db/orm_interface.h new file mode 100644 index 0000000..62ec073 --- /dev/null +++ b/modules/db/include/dpl/db/orm_interface.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file orm_interface.h + * @author Lukasz Marek (l.marek@samsung.com) + * @version 1.0 + */ + +#include +#include + +#ifndef DPL_ORM_INTERFACE_H +#define DPL_ORM_INTERFACE_H + +namespace DPL { +namespace DB { +namespace ORM { +class IOrmInterface +{ + public: + virtual ~IOrmInterface() {} + virtual DPL::DB::SqlConnection::DataCommand *AllocDataCommand( + const std::string &statement) = 0; + virtual void FreeDataCommand(DPL::DB::SqlConnection::DataCommand *command) + = 0; + virtual void TransactionBegin() = 0; + virtual void TransactionCommit() = 0; + virtual void TransactionRollback() = 0; + virtual DPL::DB::SqlConnection::RowID GetLastInsertRowID() = 0; +}; +} +} +} + +#endif diff --git a/modules/db/include/dpl/db/orm_macros.h b/modules/db/include/dpl/db/orm_macros.h new file mode 100644 index 0000000..a038523 --- /dev/null +++ b/modules/db/include/dpl/db/orm_macros.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file orm_macros.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL input file from + * database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. + +#define CREATE_TABLE(name) CREATE TABLE name( +#define COLUMN(name, type, ...) name type __VA_ARGS__, +#define COLUMN_NOT_NULL(name, type, ...) name type __VA_ARGS__ not null, +#define SQL(...) __VA_ARGS__ +#define TABLE_CONSTRAINTS(...) __VA_ARGS__, +#define CREATE_TABLE_END() CHECK(1) ); +#define DATABASE_START(db_name) +#define DATABASE_END() + diff --git a/modules/db/include/dpl/db/sql_connection.h b/modules/db/include/dpl/db/sql_connection.h new file mode 100644 index 0000000..d1eab36 --- /dev/null +++ b/modules/db/include/dpl/db/sql_connection.h @@ -0,0 +1,513 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file sql_connection.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of SQL connection + */ +#ifndef DPL_SQL_CONNECTION_H +#define DPL_SQL_CONNECTION_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DB { +/** + * SQL connection class + */ +class SqlConnection +{ + public: + /** + * SQL Exception classes + */ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, SyntaxError) + DECLARE_EXCEPTION_TYPE(Base, ConnectionBroken) + DECLARE_EXCEPTION_TYPE(Base, InternalError) + DECLARE_EXCEPTION_TYPE(Base, InvalidColumn) + }; + + typedef int ColumnIndex; + typedef int ArgumentIndex; + + /* + * SQL processed data command + */ + class DataCommand : + private Noncopyable + { + private: + SqlConnection *m_masterConnection; + sqlite3_stmt *m_stmt; + + void CheckBindResult(int result); + void CheckColumnIndex(SqlConnection::ColumnIndex column); + + DataCommand(SqlConnection *connection, const char *buffer); + + friend class SqlConnection; + + public: + virtual ~DataCommand(); + + /** + * Bind null to the prepared statement argument + * + * @param position Index of argument to bind value to + */ + void BindNull(ArgumentIndex position); + + /** + * Bind int to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInteger(ArgumentIndex position, int value); + + /** + * Bind int8_t to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt8(ArgumentIndex position, int8_t value); + + /** + * Bind int16 to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt16(ArgumentIndex position, int16_t value); + + /** + * Bind int32 to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt32(ArgumentIndex position, int32_t value); + + /** + * Bind int64 to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt64(ArgumentIndex position, int64_t value); + + /** + * Bind float to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindFloat(ArgumentIndex position, float value); + + /** + * Bind double to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindDouble(ArgumentIndex position, double value); + + /** + * Bind string to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindString(ArgumentIndex position, const char *value); + + /** + * Bind string to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindString(ArgumentIndex position, const String& value); + + /** + * Bind optional int to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInteger(ArgumentIndex position, const Optional &value); + + /** + * Bind optional int8 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt8(ArgumentIndex position, const Optional &value); + + /** + * Bind optional int16 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt16(ArgumentIndex position, const Optional &value); + + /** + * Bind optional int32 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt32(ArgumentIndex position, const Optional &value); + + /** + * Bind optional int64 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt64(ArgumentIndex position, const Optional &value); + + /** + * Bind optional float to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindFloat(ArgumentIndex position, const Optional &value); + + /** + * Bind optional double to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindDouble(ArgumentIndex position, const Optional &value); + + /** + * Bind optional string to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindString(ArgumentIndex position, const Optional &value); + + /** + * Execute the prepared statement and/or move + * to the next row of the result + * + * @return True when there was a row returned + */ + bool Step(); + + /** + * Reset prepared statement's arguments + * All parameters will become null + */ + void Reset(); + + /** + * Checks whether column value is null + * + * @throw Exception::InvalidColumn + */ + bool IsColumnNull(ColumnIndex column); + + /** + * Get integer value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int GetColumnInteger(ColumnIndex column); + + /** + * Get int8 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int8_t GetColumnInt8(ColumnIndex column); + + /** + * Get int16 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int16_t GetColumnInt16(ColumnIndex column); + /** + * Get int32 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int32_t GetColumnInt32(ColumnIndex column); + + /** + * Get int64 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int64_t GetColumnInt64(ColumnIndex column); + + /** + * Get float value from column in current row. + * + * @throw Exception::InvalidColumn + */ + float GetColumnFloat(ColumnIndex column); + + /** + * Get double value from column in current row. + * + * @throw Exception::InvalidColumn + */ + double GetColumnDouble(ColumnIndex column); + + /** + * Get string value from column in current row. + * + * @throw Exception::InvalidColumn + */ + std::string GetColumnString(ColumnIndex column); + + /** + * Get optional integer value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalInteger(ColumnIndex column); + + /** + * Get optional int8 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalInt8(ColumnIndex column); + + /** + * Get optional int16value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalInt16(ColumnIndex column); + + /** + * Get optional int32 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalInt32(ColumnIndex column); + + /** + * Get optional int64 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalInt64(ColumnIndex column); + + /** + * Get optional float value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalFloat(ColumnIndex column); + + /** + * Get optional double value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalDouble(ColumnIndex column); + + /** + * Get optional string value from column in current row. + * + * @throw Exception::InvalidColumn + */ + Optional GetColumnOptionalString(ColumnIndex column); + }; + + // Move on copy semantics + typedef std::auto_ptr DataCommandAutoPtr; + + // Open flags + class Flag + { + public: + enum Type + { + None = 1 << 0, + UseLucene = 1 << 1 + }; + + enum Option + { + RO = SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READONLY, + /** + * *TODO: please remove CREATE option from RW flag when all places + * that need that switched do CRW + */ + RW = SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE, + CRW = RW | SQLITE_OPEN_CREATE + }; + }; + + // RowID + typedef sqlite3_int64 RowID; + + /** + * Synchronization object used to synchronize SQL connection + * to the same database across different threads and processes + */ + class SynchronizationObject + { + public: + virtual ~SynchronizationObject() {} + + /** + * Synchronizes SQL connection for multiple clients. + */ + virtual void Synchronize() = 0; + + /** + * Notify all waiting clients that the connection is no longer locked. + */ + virtual void NotifyAll() = 0; + }; + + protected: + sqlite3 *m_connection; + + // Options + bool m_usingLucene; + + // Stored data procedures + int m_dataCommandsCount; + + // Synchronization object + std::unique_ptr m_synchronizationObject; + + virtual void Connect(const std::string &address, + Flag::Type = Flag::None, Flag::Option = Flag::RO); + virtual void Disconnect(); + + void TurnOnForeignKeys(); + + static SynchronizationObject *AllocDefaultSynchronizationObject(); + + public: + /** + * Open SQL connection + * + * Synchronization is archieved by using provided asynchronization object. + * If synchronizationObject is set to NULL, so synchronization is performed. + * Ownership of the synchronization object is transfered to sql connection + * object. + * + * @param address Database file name + * @param flags Open flags + * @param synchronizationObject A synchronization object to use. + */ + explicit SqlConnection(const std::string &address = std::string(), + Flag::Type flags = Flag::None, + Flag::Option options = Flag::RO, + SynchronizationObject *synchronizationObject = + AllocDefaultSynchronizationObject()); + + /** + * Destructor + */ + virtual ~SqlConnection(); + + /** + * Execute SQL command without result + * + * @param format + * @param ... + */ + void ExecCommand(const char *format, ...) DPL_DEPRECATED_WITH_MESSAGE( + "To prevent sql injection do not use this \ + method for direct sql execution"); + + /** + * Execute BEGIN; command to start new transaction + * + */ + void BeginTransaction(); + + /** + * Execute ROLLBACK; command to discard changes made + * + */ + void RollbackTransaction(); + + /** + * Execute COMMIT; command to commit changes in database + * + */ + void CommitTransaction(); + + /** + * Prepare stored procedure + * + * @param format SQL statement + * @return Data command representing stored procedure + */ + DataCommandAutoPtr PrepareDataCommand(const char *format, ...); + + /** + * Check whether given table exists + * + * @param tableName Name of the table to check + * @return True if given table name exists + */ + bool CheckTableExist(const char *tableName); + + /** + * Get last insert operation new row id + * + * @return Row ID + */ + RowID GetLastInsertRowID() const; +}; +} // namespace DB +} // namespace DPL + +#endif // DPL_SQL_CONNECTION_H diff --git a/modules/db/include/dpl/db/thread_database_support.h b/modules/db/include/dpl/db/thread_database_support.h new file mode 100644 index 0000000..04ec923 --- /dev/null +++ b/modules/db/include/dpl/db/thread_database_support.h @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread_database_support.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk) + * @version 1.0 + * @brief This file contains the declaration of thread database support + */ + +#ifndef DPL_THREAD_DATABASE_SUPPORT_H +#define DPL_THREAD_DATABASE_SUPPORT_H + +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DB { +/** + * Thread database support + * + * Associate database connection with thread lifecycle + * + */ + +class ThreadDatabaseSupport : + public DPL::DB::ORM::IOrmInterface +{ + private: + typedef DPL::DB::SqlConnection *SqlConnectionPtr; + typedef DPL::ThreadLocalVariable TLVSqlConnectionPtr; + typedef DPL::ThreadLocalVariable TLVSizeT; + typedef DPL::ThreadLocalVariable TLVBool; + + TLVSqlConnectionPtr m_connection; + TLVBool m_linger; + TLVSizeT m_refCounter; + TLVSizeT m_transactionDepth; + TLVSizeT m_attachCount; + TLVBool m_transactionCancel; + std::string m_address; + DPL::DB::SqlConnection::Flag::Type m_flags; + + TLVSqlConnectionPtr &Connection() + { + return m_connection; + } + + TLVBool &Linger() + { + return m_linger; + } + + TLVSizeT &RefCounter() + { + return m_refCounter; + } + + TLVSizeT &TransactionDepth() + { + return m_transactionDepth; + } + + TLVSizeT &AttachCount() + { + return m_attachCount; + } + + TLVBool &TransactionCancel() + { + return m_transactionCancel; + } + + void CheckedConnectionDelete() + { + Assert(!Connection().IsNull()); + Assert(*Linger() == true); + + if (*RefCounter() > 0 || *AttachCount() > 0) { + return; + } + + // Destroy connection + LogDebug("Destroying thread database connection: " << m_address); + + delete *Connection(); + + // Blocking destroy + Connection().GuardValue(false); + Linger().GuardValue(false); + RefCounter().GuardValue(false); + TransactionCancel().GuardValue(false); + TransactionDepth().GuardValue(false); + AttachCount().GuardValue(false); + + Connection().Reset(); + Linger().Reset(); + RefCounter().Reset(); + TransactionCancel().Reset(); + TransactionDepth().Reset(); + AttachCount().Reset(); + } + + void TransactionUnref() + { + LogPedantic("Unref transaction"); + + if (--(*TransactionDepth()) == 0) { + LogPedantic("Transaction is finalized"); + + if (*TransactionCancel()) { + LogPedantic("Transaction will be rolled back"); + (*Connection())->RollbackTransaction(); + } else { + LogPedantic("Transaction will be commited"); + (*Connection())->CommitTransaction(); + } + } + } + + public: + ThreadDatabaseSupport(const std::string &address, + DPL::DB::SqlConnection::Flag::Type flags) : + m_address(address), + m_flags(flags) + {} + + virtual ~ThreadDatabaseSupport() + {} + + void AttachToThread( + DPL::DB::SqlConnection::Flag::Option options = + DPL::DB::SqlConnection::Flag::RO) + { + Linger() = false; + + if (!Connection().IsNull()) { + // Add reference + ++*AttachCount(); + return; + } + + // Initialize SQL connection described in traits + LogDebug("Attaching thread database connection: " << m_address); + + Connection() = new DPL::DB::SqlConnection( + m_address.c_str(), m_flags, options); + + RefCounter() = 0; + + AttachCount() = 1; + + //Init Transaction related variables + TransactionDepth() = 0; + TransactionCancel() = false; + + // Blocking destroy + Connection().GuardValue(true); + Linger().GuardValue(true); + RefCounter().GuardValue(true); + TransactionDepth().GuardValue(true); + AttachCount().GuardValue(true); + TransactionCancel().GuardValue(true); + } + + void DetachFromThread() + { + // Calling thread must support thread database connections + Assert(!Connection().IsNull()); + + // Remove reference + --*AttachCount(); + + if (*AttachCount() > 0) { + return; + } + + // It must not be in linger state yet + Assert(*Linger() == false); + + LogDebug("Detaching thread database connection: " << m_address); + + // Enter linger state + *Linger() = true; + + // Checked delete + CheckedConnectionDelete(); + } + + bool IsAttached() + { + return !AttachCount().IsNull() && *AttachCount() > 0; + } + + DPL::DB::SqlConnection::DataCommand *AllocDataCommand( + const std::string &statement) + { + // Calling thread must support thread database connections + Assert(!Connection().IsNull()); + + // Calling thread must not be in linger state + Assert(*Linger() == false); + + // Add reference + ++*RefCounter(); + + // Create new unmanaged data command + return (*Connection())->PrepareDataCommand(statement.c_str()).release(); + } + + void FreeDataCommand(DPL::DB::SqlConnection::DataCommand *command) + { + // Calling thread must support thread database connections + Assert(!Connection().IsNull()); + + // Delete data command + delete command; + + // Unreference SQL connection + --*RefCounter(); + + // If it is linger state, connection may be destroyed + if (*Linger() == true) { + CheckedConnectionDelete(); + } + } + + void TransactionBegin() + { + // Calling thread must support thread database connections + Assert(!Connection().IsNull()); + + LogPedantic("Begin transaction"); + + // Addref transaction + if (++(*TransactionDepth()) == 1) { + LogPedantic("Transaction is initialized"); + + TransactionCancel() = false; + (*Connection())->BeginTransaction(); + } + } + + void TransactionCommit() + { + // Calling thread must support thread database connections + Assert(!Connection().IsNull()); + + LogPedantic("Commit transaction"); + + // Unref transation + TransactionUnref(); + } + + void TransactionRollback() + { + // Calling thread must support thread database connections + Assert(!Connection().IsNull()); + + // Cancel and unref transaction + TransactionCancel() = true; + TransactionUnref(); + } + + DPL::DB::SqlConnection::RowID GetLastInsertRowID() + { + // Calling thread must support thread database connections + Assert(!Connection().IsNull()); + + return (*Connection())->GetLastInsertRowID(); + } + + bool CheckTableExist(const char *name) + { + // Calling thread must support thread database connections + Assert(!Connection().IsNull()); + + return (*Connection())->CheckTableExist(name); + } +}; +} +} + +#endif // DPL_THREAD_DATABASE_SUPPORT_H diff --git a/modules/db/src/naive_synchronization_object.cpp b/modules/db/src/naive_synchronization_object.cpp new file mode 100644 index 0000000..1ac71ca --- /dev/null +++ b/modules/db/src/naive_synchronization_object.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file naive_synchronization_object.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of SQL naive + * synchronization object + */ +#include +#include +#include + +namespace { + unsigned int seed = time(NULL); +} + +namespace DPL { +namespace DB { +void NaiveSynchronizationObject::Synchronize() +{ + // Sleep for about 10ms - 30ms + Thread::MiliSleep(10 + rand_r(&seed) % 20); +} + +void NaiveSynchronizationObject::NotifyAll() +{ + // No need to inform about anything +} +} // namespace DB +} // namespace DPL diff --git a/modules/db/src/orm.cpp b/modules/db/src/orm.cpp new file mode 100644 index 0000000..c69415d --- /dev/null +++ b/modules/db/src/orm.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file orm.cpp + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Static definitions and function template specialziations of + * DPL-ORM. + */ +#include +#include + +namespace DPL { +namespace DB { +namespace ORM { +namespace RelationTypes { +const char Equal[] = "="; +const char LessThan[] = "<"; +const char And[] = "AND"; +const char Or[] = "OR"; +const char Is[] = "IS"; +const char In[] = "IN"; +} + +template<> +int GetColumnFromCommand(ColumnIndex columnIndex, + DataCommand *command) +{ + return command->GetColumnInteger(columnIndex); +} + +template<> +DPL::String GetColumnFromCommand(ColumnIndex columnIndex, + DataCommand *command) +{ + return DPL::FromUTF8String(command->GetColumnString(columnIndex)); +} + +template<> +OptionalInteger GetColumnFromCommand(ColumnIndex columnIndex, + DataCommand *command) +{ + return command->GetColumnOptionalInteger(columnIndex); +} + +template<> +OptionalString GetColumnFromCommand(ColumnIndex columnIndex, + DataCommand *command) +{ + return command->GetColumnOptionalString(columnIndex); +} + +template<> +double GetColumnFromCommand(ColumnIndex columnIndex, + DataCommand *command) +{ + return command->GetColumnDouble(columnIndex); +} + +void DataCommandUtils::BindArgument(DataCommand *command, + ArgumentIndex index, + int argument) +{ + command->BindInteger(index, argument); +} + +void DataCommandUtils::BindArgument(DataCommand *command, + ArgumentIndex index, + const OptionalInteger& argument) +{ + command->BindInteger(index, argument); +} + +void DataCommandUtils::BindArgument(DataCommand *command, + ArgumentIndex index, + const DPL::String& argument) +{ + command->BindString(index, argument); +} + +void DataCommandUtils::BindArgument(DataCommand *command, + ArgumentIndex index, + const OptionalString& argument) +{ + command->BindString(index, argument); +} +} +} +} diff --git a/modules/db/src/sql_connection.cpp b/modules/db/src/sql_connection.cpp new file mode 100644 index 0000000..60c6621 --- /dev/null +++ b/modules/db/src/sql_connection.cpp @@ -0,0 +1,869 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file sql_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of SQL connection + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DB { +namespace // anonymous +{ +class ScopedNotifyAll : + public Noncopyable +{ + private: + SqlConnection::SynchronizationObject *m_synchronizationObject; + + public: + explicit ScopedNotifyAll( + SqlConnection::SynchronizationObject *synchronizationObject) : + m_synchronizationObject(synchronizationObject) + {} + + ~ScopedNotifyAll() + { + if (!m_synchronizationObject) { + return; + } + + LogPedantic("Notifying after successful synchronize"); + m_synchronizationObject->NotifyAll(); + } +}; +} // namespace anonymous + +SqlConnection::DataCommand::DataCommand(SqlConnection *connection, + const char *buffer) : + m_masterConnection(connection), + m_stmt(NULL) +{ + Assert(connection != NULL); + + // Notify all after potentially synchronized database connection access + ScopedNotifyAll notifyAll(connection->m_synchronizationObject.get()); + + for (;;) { + int ret = sqlite3_prepare_v2(connection->m_connection, + buffer, strlen(buffer), + &m_stmt, NULL); + + if (ret == SQLITE_OK) { + LogPedantic("Data command prepared successfuly"); + break; + } else if (ret == SQLITE_BUSY) { + LogPedantic("Collision occurred while preparing SQL command"); + + // Synchronize if synchronization object is available + if (connection->m_synchronizationObject) { + LogPedantic("Performing synchronization"); + connection->m_synchronizationObject->Synchronize(); + continue; + } + + // No synchronization object defined. Fail. + } + + // Fatal error + const char *error = sqlite3_errmsg(m_masterConnection->m_connection); + + LogPedantic("SQL prepare data command failed"); + LogPedantic(" Statement: " << buffer); + LogPedantic(" Error: " << error); + + ThrowMsg(Exception::SyntaxError, error); + } + + LogPedantic("Prepared data command: " << buffer); + + // Increment stored data command count + ++m_masterConnection->m_dataCommandsCount; +} + +SqlConnection::DataCommand::~DataCommand() +{ + LogPedantic("SQL data command finalizing"); + + if (sqlite3_finalize(m_stmt) != SQLITE_OK) { + LogPedantic("Failed to finalize data command"); + } + + // Decrement stored data command count + --m_masterConnection->m_dataCommandsCount; +} + +void SqlConnection::DataCommand::CheckBindResult(int result) +{ + if (result != SQLITE_OK) { + const char *error = sqlite3_errmsg( + m_masterConnection->m_connection); + + LogPedantic("Failed to bind SQL statement parameter"); + LogPedantic(" Error: " << error); + + ThrowMsg(Exception::SyntaxError, error); + } +} + +void SqlConnection::DataCommand::BindNull( + SqlConnection::ArgumentIndex position) +{ + CheckBindResult(sqlite3_bind_null(m_stmt, position)); + LogPedantic("SQL data command bind null: [" + << position << "]"); +} + +void SqlConnection::DataCommand::BindInteger( + SqlConnection::ArgumentIndex position, + int value) +{ + CheckBindResult(sqlite3_bind_int(m_stmt, position, value)); + LogPedantic("SQL data command bind integer: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindInt8( + SqlConnection::ArgumentIndex position, + int8_t value) +{ + CheckBindResult(sqlite3_bind_int(m_stmt, position, + static_cast(value))); + LogPedantic("SQL data command bind int8: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindInt16( + SqlConnection::ArgumentIndex position, + int16_t value) +{ + CheckBindResult(sqlite3_bind_int(m_stmt, position, + static_cast(value))); + LogPedantic("SQL data command bind int16: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindInt32( + SqlConnection::ArgumentIndex position, + int32_t value) +{ + CheckBindResult(sqlite3_bind_int(m_stmt, position, + static_cast(value))); + LogPedantic("SQL data command bind int32: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindInt64( + SqlConnection::ArgumentIndex position, + int64_t value) +{ + CheckBindResult(sqlite3_bind_int64(m_stmt, position, + static_cast(value))); + LogPedantic("SQL data command bind int64: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindFloat( + SqlConnection::ArgumentIndex position, + float value) +{ + CheckBindResult(sqlite3_bind_double(m_stmt, position, + static_cast(value))); + LogPedantic("SQL data command bind float: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindDouble( + SqlConnection::ArgumentIndex position, + double value) +{ + CheckBindResult(sqlite3_bind_double(m_stmt, position, value)); + LogPedantic("SQL data command bind double: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindString( + SqlConnection::ArgumentIndex position, + const char *value) +{ + if (!value) { + BindNull(position); + return; + } + + // Assume that text may disappear + CheckBindResult(sqlite3_bind_text(m_stmt, position, + value, strlen(value), + SQLITE_TRANSIENT)); + + LogPedantic("SQL data command bind string: [" + << position << "] -> " << value); +} + +void SqlConnection::DataCommand::BindString( + SqlConnection::ArgumentIndex position, + const String &value) +{ + BindString(position, ToUTF8String(value).c_str()); +} + +void SqlConnection::DataCommand::BindInteger( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) { + BindNull(position); + } else { + BindInteger(position, *value); + } +} + +void SqlConnection::DataCommand::BindInt8( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) { + BindNull(position); + } else { + BindInt8(position, *value); + } +} + +void SqlConnection::DataCommand::BindInt16( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) { + BindNull(position); + } else { + BindInt16(position, *value); + } +} + +void SqlConnection::DataCommand::BindInt32( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) { + BindNull(position); + } else { + BindInt32(position, *value); + } +} + +void SqlConnection::DataCommand::BindInt64( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) { + BindNull(position); + } else { + BindInt64(position, *value); + } +} + +void SqlConnection::DataCommand::BindFloat( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) { + BindNull(position); + } else { + BindFloat(position, *value); + } +} + +void SqlConnection::DataCommand::BindDouble( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (value.IsNull()) { + BindNull(position); + } else { + BindDouble(position, *value); + } +} + +void SqlConnection::DataCommand::BindString( + SqlConnection::ArgumentIndex position, + const Optional &value) +{ + if (!!value) { + BindString(position, ToUTF8String(*value).c_str()); + } else { + BindNull(position); + } +} + +bool SqlConnection::DataCommand::Step() +{ + // Notify all after potentially synchronized database connection access + ScopedNotifyAll notifyAll( + m_masterConnection->m_synchronizationObject.get()); + + for (;;) { + int ret = sqlite3_step(m_stmt); + + if (ret == SQLITE_ROW) { + LogPedantic("SQL data command step ROW"); + return true; + } else if (ret == SQLITE_DONE) { + LogPedantic("SQL data command step DONE"); + return false; + } else if (ret == SQLITE_BUSY) { + LogPedantic("Collision occurred while executing SQL command"); + + // Synchronize if synchronization object is available + if (m_masterConnection->m_synchronizationObject) { + LogPedantic("Performing synchronization"); + + m_masterConnection-> + m_synchronizationObject->Synchronize(); + + continue; + } + + // No synchronization object defined. Fail. + } + + // Fatal error + const char *error = sqlite3_errmsg(m_masterConnection->m_connection); + + LogPedantic("SQL step data command failed"); + LogPedantic(" Error: " << error); + + ThrowMsg(Exception::InternalError, error); + } +} + +void SqlConnection::DataCommand::Reset() +{ + /* + * According to: + * http://www.sqlite.org/c3ref/stmt.html + * + * if last sqlite3_step command on this stmt returned an error, + * then sqlite3_reset will return that error, althought it is not an error. + * So sqlite3_reset allways succedes. + */ + sqlite3_reset(m_stmt); + + LogPedantic("SQL data command reset"); +} + +void SqlConnection::DataCommand::CheckColumnIndex( + SqlConnection::ColumnIndex column) +{ + if (column < 0 || column >= sqlite3_column_count(m_stmt)) { + ThrowMsg(Exception::InvalidColumn, "Column index is out of bounds"); + } +} + +bool SqlConnection::DataCommand::IsColumnNull( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column type: [" << column << "]"); + CheckColumnIndex(column); + return sqlite3_column_type(m_stmt, column) == SQLITE_NULL; +} + +int SqlConnection::DataCommand::GetColumnInteger( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column integer: [" << column << "]"); + CheckColumnIndex(column); + int value = sqlite3_column_int(m_stmt, column); + LogPedantic(" Value: " << value); + return value; +} + +int8_t SqlConnection::DataCommand::GetColumnInt8( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column int8: [" << column << "]"); + CheckColumnIndex(column); + int8_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; +} + +int16_t SqlConnection::DataCommand::GetColumnInt16( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column int16: [" << column << "]"); + CheckColumnIndex(column); + int16_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; +} + +int32_t SqlConnection::DataCommand::GetColumnInt32( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column int32: [" << column << "]"); + CheckColumnIndex(column); + int32_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; +} + +int64_t SqlConnection::DataCommand::GetColumnInt64( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column int64: [" << column << "]"); + CheckColumnIndex(column); + int64_t value = static_cast(sqlite3_column_int64(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; +} + +float SqlConnection::DataCommand::GetColumnFloat( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column float: [" << column << "]"); + CheckColumnIndex(column); + float value = static_cast(sqlite3_column_double(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; +} + +double SqlConnection::DataCommand::GetColumnDouble( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column double: [" << column << "]"); + CheckColumnIndex(column); + double value = sqlite3_column_double(m_stmt, column); + LogPedantic(" Value: " << value); + return value; +} + +std::string SqlConnection::DataCommand::GetColumnString( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column string: [" << column << "]"); + CheckColumnIndex(column); + + const char *value = reinterpret_cast( + sqlite3_column_text(m_stmt, column)); + + LogPedantic("Value: " << (value ? value : "NULL")); + + if (value == NULL) { + return std::string(); + } + + return std::string(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalInteger( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional integer: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) { + return Optional::Null; + } + int value = sqlite3_column_int(m_stmt, column); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalInt8( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional int8: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) { + return Optional::Null; + } + int8_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalInt16( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional int16: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) { + return Optional::Null; + } + int16_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalInt32( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional int32: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) { + return Optional::Null; + } + int32_t value = static_cast(sqlite3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalInt64( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional int64: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) { + return Optional::Null; + } + int64_t value = static_cast(sqlite3_column_int64(m_stmt, column)); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalFloat( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional float: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) { + return Optional::Null; + } + float value = static_cast(sqlite3_column_double(m_stmt, column)); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalDouble( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional double: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) { + return Optional::Null; + } + double value = sqlite3_column_double(m_stmt, column); + LogPedantic(" Value: " << value); + return Optional(value); +} + +Optional SqlConnection::DataCommand::GetColumnOptionalString( + SqlConnection::ColumnIndex column) +{ + LogPedantic("SQL data command get column optional string: [" + << column << "]"); + CheckColumnIndex(column); + if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) { + return Optional::Null; + } + const char *value = reinterpret_cast( + sqlite3_column_text(m_stmt, column)); + LogPedantic("Value: " << value); + String s = FromUTF8String(value); + return Optional(s); +} + +void SqlConnection::Connect(const std::string &address, + Flag::Type type, + Flag::Option flag) +{ + if (m_connection != NULL) { + LogPedantic("Already connected."); + return; + } + LogPedantic("Connecting to DB: " << address << "..."); + + // Connect to database + int result = -1; + int retry = 5; + while( result != SQLITE_OK){ + if (type & Flag::UseLucene) { + result = db_util_open_with_options( + address.c_str(), + &m_connection, + flag, + NULL); + + m_usingLucene = true; + LogPedantic("Lucene index enabled"); + } else { + result = sqlite3_open_v2( + address.c_str(), + &m_connection, + flag, + NULL); + + m_usingLucene = false; + LogPedantic("Lucene index disabled"); + } + + if (result == SQLITE_OK) { + LogPedantic("Connected to DB"); + } else { + LogPedantic("Failed to connect to DB! ret="<BindString(1, tableName); + + if (!command->Step()) { + LogPedantic("No matching records in table"); + return false; + } + + return command->GetColumnString(0) == tableName; +} + +SqlConnection::SqlConnection(const std::string &address, + Flag::Type flag, + Flag::Option option, + SynchronizationObject *synchronizationObject) : + m_connection(NULL), + m_usingLucene(false), + m_dataCommandsCount(0), + m_synchronizationObject(synchronizationObject) +{ + LogPedantic("Opening database connection to: " << address); + + // Connect to DB + SqlConnection::Connect(address, flag, option); + + if (!m_synchronizationObject) { + LogPedantic("No synchronization object defined"); + } +} + +SqlConnection::~SqlConnection() +{ + LogPedantic("Closing database connection"); + + // Disconnect from DB + Try + { + SqlConnection::Disconnect(); + } + Catch(Exception::Base) + { + LogPedantic("Failed to disconnect from database"); + } +} + +void SqlConnection::ExecCommand(const char *format, ...) +{ + if (m_connection == NULL) { + LogPedantic("Cannot execute command. Not connected to DB!"); + return; + } + + if (format == NULL) { + LogPedantic("Null query!"); + ThrowMsg(Exception::SyntaxError, "Null statement"); + } + + char *rawBuffer; + + va_list args; + va_start(args, format); + + if (vasprintf(&rawBuffer, format, args) == -1) { + rawBuffer = NULL; + } + + va_end(args); + + ScopedFree buffer(rawBuffer); + + if (!buffer) { + LogPedantic("Failed to allocate statement string"); + return; + } + + LogPedantic("Executing SQL command: " << buffer.Get()); + + // Notify all after potentially synchronized database connection access + ScopedNotifyAll notifyAll(m_synchronizationObject.get()); + + for (;;) { + char *errorBuffer; + + int ret = sqlite3_exec(m_connection, + buffer.Get(), + NULL, + NULL, + &errorBuffer); + + std::string errorMsg; + + // Take allocated error buffer + if (errorBuffer != NULL) { + errorMsg = errorBuffer; + sqlite3_free(errorBuffer); + } + + if (ret == SQLITE_OK) { + return; + } + + if (ret == SQLITE_BUSY) { + LogPedantic("Collision occurred while executing SQL command"); + + // Synchronize if synchronization object is available + if (m_synchronizationObject) { + LogPedantic("Performing synchronization"); + m_synchronizationObject->Synchronize(); + continue; + } + + // No synchronization object defined. Fail. + } + + // Fatal error + LogPedantic("Failed to execute SQL command. Error: " << errorMsg); + ThrowMsg(Exception::SyntaxError, errorMsg); + } +} + +SqlConnection::DataCommandAutoPtr SqlConnection::PrepareDataCommand( + const char *format, + ...) +{ + if (m_connection == NULL) { + LogPedantic("Cannot execute data command. Not connected to DB!"); + return DataCommandAutoPtr(); + } + + char *rawBuffer; + + va_list args; + va_start(args, format); + + if (vasprintf(&rawBuffer, format, args) == -1) { + rawBuffer = NULL; + } + + va_end(args); + + ScopedFree buffer(rawBuffer); + + if (!buffer) { + LogPedantic("Failed to allocate statement string"); + return DataCommandAutoPtr(); + } + + LogPedantic("Executing SQL data command: " << buffer.Get()); + + return DataCommandAutoPtr(new DataCommand(this, buffer.Get())); +} + +SqlConnection::RowID SqlConnection::GetLastInsertRowID() const +{ + return static_cast(sqlite3_last_insert_rowid(m_connection)); +} + +void SqlConnection::TurnOnForeignKeys() +{ + ExecCommand("PRAGMA foreign_keys = ON;"); +} + +void SqlConnection::BeginTransaction() +{ + ExecCommand("BEGIN;"); +} + +void SqlConnection::RollbackTransaction() +{ + ExecCommand("ROLLBACK;"); +} + +void SqlConnection::CommitTransaction() +{ + ExecCommand("COMMIT;"); +} + +SqlConnection::SynchronizationObject * +SqlConnection::AllocDefaultSynchronizationObject() +{ + return new NaiveSynchronizationObject(); +} +} // namespace DB +} // namespace DPL diff --git a/modules/db/src/thread_database_support.cpp b/modules/db/src/thread_database_support.cpp new file mode 100644 index 0000000..101640f --- /dev/null +++ b/modules/db/src/thread_database_support.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread_database_support.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk) + * @version 1.0 + * @brief This file contains the definition of thread database support + */ +#include +#include \ No newline at end of file diff --git a/modules/dbus/config.cmake b/modules/dbus/config.cmake new file mode 100644 index 0000000..f2fefde --- /dev/null +++ b/modules/dbus/config.cmake @@ -0,0 +1,56 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_DBUS_SOURCES + ${PROJECT_SOURCE_DIR}/modules/dbus/src/connection.cpp + ${PROJECT_SOURCE_DIR}/modules/dbus/src/dispatcher.cpp + ${PROJECT_SOURCE_DIR}/modules/dbus/src/interface.cpp + ${PROJECT_SOURCE_DIR}/modules/dbus/src/object.cpp + ${PROJECT_SOURCE_DIR}/modules/dbus/src/object_proxy.cpp + ${PROJECT_SOURCE_DIR}/modules/dbus/src/server.cpp + PARENT_SCOPE +) + + +SET(DPL_DBUS_HEADERS + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/connection.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/dbus_client.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/dbus_deserialization.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/dbus_interface_dispatcher.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/dbus_serialization.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/dbus_server_deserialization.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/dbus_server_serialization.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/dbus_signature.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/dispatcher.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/glib_util.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/exception.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/interface.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/method_proxy.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/object.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/object_proxy.h + ${PROJECT_SOURCE_DIR}/modules/dbus/include/dpl/dbus/server.h + PARENT_SCOPE +) + +SET(DPL_DBUS_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/dbus/include + PARENT_SCOPE +) diff --git a/modules/dbus/include/dpl/dbus/connection.h b/modules/dbus/include/dpl/dbus/connection.h new file mode 100644 index 0000000..4a455ad --- /dev/null +++ b/modules/dbus/include/dpl/dbus/connection.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file connection.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_CONNECTION_H +#define DPL_DBUS_CONNECTION_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +namespace ConnectionEvents { +/** + * Emitted when service name is acquired. + * + * Arg0 Acquired name. + */ +DECLARE_GENERIC_EVENT_1(ServiceNameAcquiredEvent, std::string) + +/** + * Emitted when service name is lost. + * + * Arg0 Lost name. + */ +DECLARE_GENERIC_EVENT_1(ServiceNameLostEvent, std::string) + +/** + * Emitted when remote host closes connection. + * + * Arg0 Low-level error message. + */ +DECLARE_GENERIC_EVENT_1(ConnectionBrokenEvent, std::string) + +/** + * Emitted when invalid or malformed data appear on connection. + * + * Arg0 Low-level error message. + */ +DECLARE_GENERIC_EVENT_1(ConnectionInvalidEvent, std::string) +} + +class Server; + +class Connection; +typedef std::shared_ptr ConnectionPtr; + +typedef std::shared_ptr ObjectProxyPtr; + +class Connection : + public DPL::Event::EventSupport, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport +{ + public: + /** + * Acquires connection to session bus. + * + * @return Session bus connection. + * @throw DBus::Exception If unable to connect to session bus. + */ + static ConnectionPtr sessionBus(); + + /** + * Acquires connection to system bus. + * + * @return System bus connection. + * @throw DBus::Exception If unable to connect to system bus. + */ + static ConnectionPtr systemBus(); + + /** + * Acquires connection to specified bus. + * + * @return Bus connection. + * @throw DBus::Exception If unable to connect to a bus. + */ + static ConnectionPtr connectTo(GBusType busType); + + /** + * Acquires connection to for specified address. + * + * @return Connection. + * @throw DBus::Exception If unable to connect. + * + * @remarks Address should be in DBus format (@see DBus documentation). + */ + static ConnectionPtr connectTo(const std::string& address); + + ~Connection(); + + /** + * Sets up a service on the connection. + * + * @param serviceName Service to register. + * @throw DBus::Exception If registration failed. + * + * @remarks Add objects before services to prevent notifications about new + * interfaces being added. + */ + void registerService(const std::string& serviceName); + + /** + * Unregisters a service from the connection. + * + * @param serviceName Service to unregister. + * @throw DBus::Exception If service not registered. + */ + void unregisterService(const std::string& serviceName); + + /** + * Adds object to the connection. + * + * @param object Object to register. + * @throw DBus::Exception If registration failed. + * + * @remarks Add objects before services to prevent notifications about new + * interfaces being added. + */ + void registerObject(const ObjectPtr& object); + + /** + * Removed object from the connection. + * + * @param objectPath Path of the object to unregister. + * @throw DBus::Exception If object not registered. + */ + void unregisterObject(const std::string& objectPath); + + /** + * Creates proxy to remote objects. + * + * @param serviceName Name of the DBus service. + * @param objectPath DBus path to the object. + * @return Object proxy. + * @throw DBus::ConnectionClosedException If connection is closed. + */ + ObjectProxyPtr createObjectProxy(const std::string& serviceName, + const std::string& objectPath); + + private: + friend class Server; + + typedef std::map RegisteredServices; + + struct ObjectRegistration + { + ObjectRegistration(guint _registrationId, const ObjectPtr& _object) : + registrationId(_registrationId), + object(_object) + {} + + guint registrationId; + ObjectPtr object; + }; + typedef std::map RegisteredObjects; + + static void onServiceNameAcquired(GDBusConnection* connection, + const gchar* serviceName, + gpointer data); + + static void onServiceNameLost(GDBusConnection* connection, + const gchar* serviceName, + gpointer data); + + static void onConnectionClosed(GDBusConnection* connection, + gboolean peerVanished, + GError* error, + gpointer data); + + explicit Connection(GDBusConnection* connection); + + GDBusConnection* m_connection; + + RegisteredServices m_registeredServices; + + RegisteredObjects m_registeredObjects; +}; +} +} + +#endif // DPL_DBUS_CONNECTION_H diff --git a/modules/dbus/include/dpl/dbus/dbus_client.h b/modules/dbus/include/dpl/dbus/dbus_client.h new file mode 100644 index 0000000..061ec46 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_client.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_client.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus generic client support + */ + +#ifndef DPL_DBUS_DBUS_CLIENT_H_ +#define DPL_DBUS_DBUS_CLIENT_H_ + +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +/* + * DBus::Client class is intended to act as simple DBus client. To call a method + * on remote service "Service", on remote object "Object", interface + * "Interface",use it like this: + * + * + * DBus::Client client("Object", "Service", "Interface"); + * (...) // variables declarations + * client.call("Method name", arg1, arg2, arg2, ... argN, + * &outArg1, &outArg2, &outArg3, ..., &outArgN); + * + * + * As You can see, input parameters of the call are passed with reference, + * output ones are passed as pointers - parameters MUST be passed this way. + * + * To call a void function (no out params), just pass in arguments to Call(). + * + * Currently client supports serialization and deserialization of simple types + * (int, char, float, unsigned), strings (std::string and char*) and + * some STL containers (std::vector, std::list, std::map, std::set, std::pair). + * Structures and classes are not (yet) supported. + */ + +class Client +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DBusClientException) + }; + + Client(std::string serverPath, + std::string serviceName, + std::string interfaceName) : + m_serviceName(serviceName), + m_serverPath(serverPath), + m_interfaceName(interfaceName) + { + DBusError error; + + dbus_error_init(&error); + m_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (NULL == m_connection) { + LogPedantic("Couldn't get DBUS connection. Error: " << + error.message); + dbus_error_free(&error); + ThrowMsg(Exception::DBusClientException, + "Couldn't get DBUS connection."); + } + } + + template + void call(const char* methodName, const Args& ... args) + { + DBusMessage* message = dbus_message_new_method_call( + m_serviceName.c_str(), + m_serverPath.c_str(), + m_interfaceName.c_str(), + methodName); + DBusMessageIter argsIterator; + dbus_message_iter_init_append(message, &argsIterator); + call(message, &argsIterator, args ...); + dbus_message_unref(message); + } + + template + void call(std::string methodName, const Args& ... args) + { + call(methodName.c_str(), args ...); + } + + ~Client() + { + dbus_connection_unref(m_connection); + } + + private: + + DBusMessage* makeCall( + DBusMessage* message) + { + DBusError error; + dbus_error_init(&error); + DBusMessage* ret = dbus_connection_send_with_reply_and_block( + m_connection, + message, + -1, + &error); + if (NULL == ret) { + LogPedantic("Error sending DBUS message: " << + error.message); + dbus_error_free(&error); + ThrowMsg(Exception::DBusClientException, + "Error sending DBUS message."); + } + return ret; + } + + void call(DBusMessage* message, DBusMessageIter* /*argsIterator*/) + { + DBusMessage* ret = makeCall(message); + if (ret != NULL) { + dbus_message_unref(ret); + } else { + LogPedantic("Error getting DBUS response."); + ThrowMsg(Exception::DBusClientException, + "Error getting DBUS response."); + } + } + + template + void call( + DBusMessage* message, + DBusMessageIter* argsIterator, + const T& invalue, + const Args& ... args) + { + if (!Serialization::serialize(argsIterator, invalue)) { + LogPedantic("Error in serialization."); + ThrowMsg(Exception::DBusClientException, + "Error in serialization."); + } + call(message, argsIterator, args ...); + } + + template + void call( + DBusMessage* message, + DBusMessageIter* argsIterator, + const T* invalue, + const Args& ... args) + { + if (!Serialization::serialize(argsIterator, invalue)) { + LogPedantic("Error in serialization."); + ThrowMsg(Exception::DBusClientException, + "Error in serialization."); + } + call(message, argsIterator, args ...); + } + + template + void call( + DBusMessage* message, + DBusMessageIter* argsIterator, + const T* invalue) + { + if (!Serialization::serialize(argsIterator, invalue)) { + LogPedantic("Error in serialization."); + ThrowMsg(Exception::DBusClientException, + "Error in serialization."); + } + call(message, argsIterator); + } + + template + void call( + DBusMessage* message, + DBusMessageIter* /*argsIterator*/, + T* out, + const Args& ... args) + { + DBusMessage* ret = makeCall(message); + if (ret != NULL) { + DBusMessageIter responseIterator; + dbus_message_iter_init(ret, &responseIterator); + returnFromCall(&responseIterator, out, args ...); + dbus_message_unref(ret); + } + } + + template + void returnFromCall( + DBusMessageIter* responseIterator, + T* out, + const Args& ... args) + { + if (!Deserialization::deserialize(responseIterator, out)) { + LogPedantic("Error in deserialization."); + ThrowMsg(Exception::DBusClientException, + "Error in deserialization."); + } + returnFromCall(responseIterator, args ...); + } + + template + void returnFromCall(DBusMessageIter* responseIterator, T* out) + { + if (!Deserialization::deserialize(responseIterator, out)) { + LogPedantic("Error in deserialization."); + ThrowMsg(Exception::DBusClientException, + "Error in deserialization."); + } + } + + std::string m_serviceName, m_serverPath, m_interfaceName; + DBusConnection* m_connection; +}; +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_CLIENT_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_deserialization.h b/modules/dbus/include/dpl/dbus/dbus_deserialization.h new file mode 100644 index 0000000..2a05db8 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_deserialization.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_deserialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus data deserialization + */ + +#ifndef DPL_DBUS_DBUS_DESERIALIZATION_H_ +#define DPL_DBUS_DBUS_DESERIALIZATION_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +struct Deserialization +{ + static bool deserializePrimitive( + DBusMessageIter* responseIterator, + void* arg, + int type) + { + if (dbus_message_iter_get_arg_type(responseIterator) != type) { + return false; + } + dbus_message_iter_get_basic(responseIterator, arg); + return true; + } + + // char* and all integer types + doubles + template + static bool deserialize(DBusMessageIter* responseIterator, T* arg) + { + if (dbus_message_iter_get_arg_type(responseIterator) + != SimpleType::value) + { + return false; + } + dbus_message_iter_get_basic(responseIterator, arg); + return true; + } + + // float case - read as double + static bool deserialize(DBusMessageIter* responseIterator, float* arg) + { + double d; + if (!deserialize(responseIterator, &d)) { + return false; + } + *arg = static_cast(d); + return true; + } + + // std::string + static bool deserialize( + DBusMessageIter* responseIterator, + std::string* arg) + { + char* str = NULL; + if (!deserialize(responseIterator, &str)) { + return false; + } + *arg = std::string(str); + return true; + } + + // dbus array deserialization + template + static bool deserializeContainer( + DBusMessageIter* responseIterator, + T* arg) + { + if (dbus_message_iter_get_arg_type(responseIterator) + != DBUS_TYPE_ARRAY) + { + return false; + } + DBusMessageIter subIterator; + dbus_message_iter_recurse(responseIterator, &subIterator); + while (dbus_message_iter_get_arg_type(&subIterator) + != DBUS_TYPE_INVALID) + { + arg->push_back(typename T::value_type()); + if (!deserialize(&subIterator, &arg->back())) { + return false; + } + dbus_message_iter_next(&subIterator); + } + return true; + } + + // std::vector + template + static bool deserialize( + DBusMessageIter* responseIterator, + std::vector* arg) + { + return deserializeContainer(responseIterator, arg); + } + + // std::list + template + static bool deserialize( + DBusMessageIter* responseIterator, + std::list* arg) + { + return deserializeContainer(responseIterator, arg); + } + + // std::set + template + static bool deserialize( + DBusMessageIter* responseIterator, + std::set* arg) + { + if (dbus_message_iter_get_arg_type(responseIterator) + != DBUS_TYPE_ARRAY) + { + return false; + } + DBusMessageIter subIterator; + dbus_message_iter_recurse(responseIterator, &subIterator); + while (dbus_message_iter_get_arg_type(&subIterator) + != DBUS_TYPE_INVALID) + { + typename std::set::value_type element; + if (!deserialize(&subIterator, &element)) { + return false; + } + arg->insert(element); + dbus_message_iter_next(&subIterator); + } + return true; + } + + // std::pair + template + static bool deserialize( + DBusMessageIter* argsIterator, + const std::pair* arg) + { + if (dbus_message_iter_get_arg_type(argsIterator) + != DBUS_TYPE_DICT_ENTRY) + { + return false; + } + DBusMessageIter dictEntryIterator; + dbus_message_iter_recurse(argsIterator, &dictEntryIterator); + if (!deserialize(dictEntryIterator, &arg->first)) { + return false; + } + dbus_message_iter_next(&dictEntryIterator); + if (!deserialize(dictEntryIterator, &arg->second)) { + return false; + } + return true; + } + + // std::map + template + static bool deserialize( + DBusMessageIter* responseIterator, + const std::map* arg) + { + if (dbus_message_iter_get_arg_type(responseIterator) + != DBUS_TYPE_ARRAY) + { + return false; + } + DBusMessageIter subIterator; + dbus_message_iter_recurse(responseIterator, &subIterator); + while (dbus_message_iter_get_arg_type(&subIterator) + != DBUS_TYPE_INVALID) + { + typename std::pair element; + if (!deserialize(&subIterator, &element)) { + return false; + } + arg->insert(element); + dbus_message_iter_next(&subIterator); + } + return true; + } +}; + +template<> +inline bool Deserialization::deserialize( + DBusMessageIter* responseIterator, + bool* arg) +{ + unsigned int value; + if (dbus_message_iter_get_arg_type(responseIterator) + != SimpleType::value) + { + return false; + } + dbus_message_iter_get_basic(responseIterator, &value); + *arg = static_cast(value); + return true; +} +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_DESERIALIZATION_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_interface_dispatcher.h b/modules/dbus/include/dpl/dbus/dbus_interface_dispatcher.h new file mode 100644 index 0000000..97d7407 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_interface_dispatcher.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file dbus_interface_dispatcher.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file contains definitions of DBus::InterfaceDispatcher + * class. + */ + +#ifndef DPL_DBUS_DBUS_INTERFACE_DISPATCHER_H_ +#define DPL_DBUS_DBUS_INTERFACE_DISPATCHER_H_ + +#include +#include +#include + +namespace DPL { +namespace DBus { +class InterfaceDispatcher : public DBus::Dispatcher +{ + public: + explicit InterfaceDispatcher(const std::string& interfaceName) : + m_interfaceName(interfaceName) + {} + + virtual ~InterfaceDispatcher() + {} + + // Implement it in specific interface with method handling + virtual void onMethodCall(const gchar* /*methodName*/, + GVariant* /*parameters*/, + GDBusMethodInvocation* /*invocation*/) = 0; + + virtual std::string getName() const + { + return m_interfaceName; + } + + virtual std::string getXmlSignature() const + { + return m_xml; + } + virtual void setXmlSignature(const std::string& newSignature) + { + m_xml = newSignature; + } + + virtual void onMethodCall(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* interfaceName, + const gchar* methodName, + GVariant* parameters, + GDBusMethodInvocation* invocation) + { + if (g_strcmp0(interfaceName, m_interfaceName.c_str()) == 0) { + onMethodCall(methodName, parameters, invocation); + } else { + LogPedantic("Called invalid interface: " << interfaceName << + " instead of: " << m_interfaceName); + } + } + + virtual GVariant* onPropertyGet(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* /*interfaceName*/, + const gchar* propertyName) + { + LogDebug("InterfaceDispatcher onPropertyGet: " << propertyName); + return NULL; + } + + virtual gboolean onPropertySet(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* /*interfaceName*/, + const gchar* propertyName, + GVariant* /*value*/) + { + LogDebug("InterfaceDispatcher onPropertySet: " << propertyName); + return false; + } + + private: + std::string m_interfaceName, m_xml; +}; +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_INTERFACE_DISPATCHER_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_serialization.h b/modules/dbus/include/dpl/dbus/dbus_serialization.h new file mode 100644 index 0000000..c0fa338 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_serialization.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_serialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus data derialization + */ + +#ifndef DPL_DBUS_DBUS_SERIALIZATION_H_ +#define DPL_DBUS_DBUS_SERIALIZATION_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +struct Serialization +{ + // std::string + static bool serialize( + DBusMessageIter* argsIterator, + const std::string& str) + { + return serialize(argsIterator, str.c_str()); + } + + // float case - send as double + static bool serialize(DBusMessageIter* argsIterator, const float& arg) + { + const double d = static_cast(arg); + return serialize(argsIterator, d); + } + + // char* and all integer types + doubles + template + static bool serialize(DBusMessageIter* argsIterator, const T& arg) + { + return dbus_message_iter_append_basic(argsIterator, + SimpleType::value, + &arg); + } + + // dbus array serialization + template + static bool serializeContainer( + DBusMessageIter* argsIterator, + const T& arg) + { + typename T::const_iterator containerIt; + DBusMessageIter subIterator; + if (!dbus_message_iter_open_container(argsIterator, DBUS_TYPE_ARRAY, + Signature + ::value(), &subIterator)) + { + return false; + } + FOREACH(containerIt, arg) { + if (!serialize(&subIterator, *containerIt)) { + return false; + } + } + return dbus_message_iter_close_container(argsIterator, &subIterator); + } + + // std::vector + template + static bool serialize( + DBusMessageIter* argsIterator, + const std::vector &arg) + { + return serializeContainer(argsIterator, arg); + } + + // std::list + template + static bool serialize( + DBusMessageIter* argsIterator, + const std::list &arg) + { + return serializeContainer(argsIterator, arg); + } + + // std::set + template + static bool serialize( + DBusMessageIter* argsIterator, + const std::set &arg) + { + return serializeContainer(argsIterator, arg); + } + + // std::pair + template + static bool serialize( + DBusMessageIter* argsIterator, + const std::pair &arg) + { + DBusMessageIter dictEntryIterator; + if (!dbus_message_iter_open_container(argsIterator, + DBUS_TYPE_DICT_ENTRY, NULL, + &dictEntryIterator)) + { + return false; + } + if (!serialize(dictEntryIterator, arg.first)) { + return false; + } + if (!serialize(dictEntryIterator, arg.second)) { + return false; + } + return dbus_message_iter_close_container(argsIterator, + &dictEntryIterator); + } + + // std::map + template + static bool serialize( + DBusMessageIter* argsIterator, + const std::map &arg) + { + return serializeContainer(argsIterator, arg); + } +}; + +// char* and all integer types + doubles +template<> +inline bool Serialization::serialize(DBusMessageIter* argsIterator, + const bool& arg) +{ + unsigned int value = static_cast(arg); + return dbus_message_iter_append_basic(argsIterator, + SimpleType::value, + &value); +} +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_SERIALIZATION_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_server_deserialization.h b/modules/dbus/include/dpl/dbus/dbus_server_deserialization.h new file mode 100644 index 0000000..eb09d6d --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_server_deserialization.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_server_deserialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus data deserialization from GVariant + */ + +#ifndef DPL_DBUS_DBUS_SERVER_DESERIALIZATION_H_ +#define DPL_DBUS_DBUS_SERVER_DESERIALIZATION_H_ + +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +struct ServerDeserialization { + template + static bool deserialize(GVariant* g, T* arg1, Args ... args) + { + Assert(NULL != g); + Assert(NULL != arg1); + GVariantIter* iterator = g_variant_iter_new(g); + if (NULL == iterator) { + return false; + } + if (!deserializeIterator(iterator, arg1)) { + g_variant_iter_free(iterator); + return false; + } + if (!deserializeIterator(iterator, args ...)) { + g_variant_iter_free(iterator); + return false; + } + g_variant_iter_free(iterator); + return true; + } + + template + static bool deserialize(GVariant* g, T* arg1) + { + Assert(NULL != g); + Assert(NULL != arg1); + GVariantIter* iterator = g_variant_iter_new(g); + if (NULL == iterator) { + return false; + } + if (!deserializeIterator(iterator, arg1)) { + g_variant_iter_free(iterator); + return false; + } + g_variant_iter_free(iterator); + return true; + } + + // deserialization from GVariant tuple iterator + template + static bool deserializeIterator(GVariantIter* g, T* arg1, Args ... args) + { + Assert(NULL != g); + Assert(NULL != arg1); + GVariant* elem = g_variant_iter_next_value(g); + if (NULL == elem) { + return false; + } + if (!deserializeElem(elem, arg1)) { + return false; + } + if (!deserializeIterator(g, args ...)) { + return false; + } + return true; + } + + template + static bool deserializeIterator(GVariantIter* g, T* arg1) + { + Assert(NULL != g); + Assert(NULL != arg1); + GVariant* elem = g_variant_iter_next_value(g); + if (NULL == elem) { + return false; + } + if (!deserializeElem(elem, arg1)) { + return false; + } + g_variant_unref(elem); + return true; + } + + // type specialization + static bool deserializeElem(GVariant* parameters, std::string* outStr) + { + const gchar* arg = g_variant_get_string(parameters, NULL); + *outStr = std::string(arg); + return true; + } + + static bool deserializeElem(GVariant* parameters, int* outInt) + { + gint32 arg = g_variant_get_int32(parameters); + *outInt = arg; + return true; + } + + static bool deserializeElem(GVariant* parameters, unsigned* outInt) + { + guint32 arg = g_variant_get_uint32(parameters); + *outInt = arg; + return true; + } + + static bool deserializeElem(GVariant* parameters, bool* outInt) + { + gboolean arg = g_variant_get_boolean(parameters); + *outInt = arg; + return true; + } + + static bool deserializeElem(GVariant* parameters, float* outInt) + { + gdouble arg = g_variant_get_double(parameters); + *outInt = static_cast(arg); + return true; + } + + static bool deserializeElem(GVariant* parameters, + std::vector* outArray) + { + unsigned int i = 0; + gsize length = 0; + const gchar** args = g_variant_get_strv( + parameters, + &length); + for (i = 0; i < length; ++i) { + outArray->push_back(std::string(args[i])); + } + g_free(args); + return true; + } + + static bool deserializeElem(GVariant* parameters, + std::list* outArray) + { + unsigned int i = 0; + gsize length = 0; + const gchar** args = g_variant_get_strv( + parameters, + &length); + for (i = 0; i < length; ++i) { + outArray->push_back(std::string(args[i])); + } + g_free(args); + return true; + } +}; +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_SERVER_DESERIALIZATION_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_server_serialization.h b/modules/dbus/include/dpl/dbus/dbus_server_serialization.h new file mode 100644 index 0000000..9e47ca6 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_server_serialization.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_server_serialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus data serialization to GVariant + */ + +#ifndef DPL_DBUS_DBUS_SERVER_SERIALIZATION_H_ +#define DPL_DBUS_DBUS_SERVER_SERIALIZATION_H_ + +#include +#include + +namespace DPL { +namespace DBus { +struct ServerSerialization { + template + static GVariant* serialize(Args ... args) + { + GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE_TUPLE); + if (NULL == builder) { + return NULL; + } + serializeBuilder(builder, args ...); + return g_variant_builder_end(builder); + } + + // serialization on GVariantBuilder + template + static void serializeBuilder(GVariantBuilder* builder, + const T& arg, + Args ... args) + { + serializeElem(builder, arg); + serializeBuilder(builder, args ...); + } + + template + static void serializeBuilder(GVariantBuilder* builder, const T& arg) + { + serializeElem(builder, arg); + } + + // type specialization + static void serializeElem(GVariantBuilder* builder, int arg) + { + g_variant_builder_add_value(builder, g_variant_new_int32(arg)); + } + + static void serializeElem(GVariantBuilder* builder, unsigned arg) + { + g_variant_builder_add_value(builder, g_variant_new_uint32(arg)); + } + + static void serializeElem(GVariantBuilder* builder, bool arg) + { + g_variant_builder_add_value(builder, g_variant_new_boolean(arg)); + } + + static void serializeElem(GVariantBuilder* builder, float arg) + { + gdouble d = static_cast(arg); + g_variant_builder_add_value(builder, g_variant_new_double(d)); + } + + static void serializeElem(GVariantBuilder* builder, const char* arg) + { + g_variant_builder_add_value(builder, g_variant_new_string(arg)); + } + + static void serializeElem(GVariantBuilder* builder, + const std::string& arg) + { + g_variant_builder_add_value(builder, g_variant_new_string(arg.c_str())); + } +}; +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_DBUS_SERVER_SERIALIZATION_H_ diff --git a/modules/dbus/include/dpl/dbus/dbus_signature.h b/modules/dbus/include/dpl/dbus/dbus_signature.h new file mode 100644 index 0000000..bc99108 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dbus_signature.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dbus_deserialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Header file for DBus data signatures + */ + +#ifndef DPL_DBUS_SIGNATURE_H +#define DPL_DBUS_SIGNATURE_H + +#include +#include + +namespace DPL { +namespace DBus { +template +struct SimpleType; + +template +struct Signature +{ + static inline const char* value() + { + static const char signature[] = + { (char) SimpleType::value, 0 }; + return signature; + } +}; + +// signed integer types +template +struct __SignedIntegerType; + +template<> +struct __SignedIntegerType<1> +{ + static const int value = DBUS_TYPE_INT16; +}; + +template<> +struct __SignedIntegerType<2> +{ + static const int value = DBUS_TYPE_INT16; +}; + +template<> +struct __SignedIntegerType<4> +{ + static const int value = DBUS_TYPE_INT32; +}; + +template<> +struct __SignedIntegerType<8> +{ + static const int value = DBUS_TYPE_INT64; +}; + +// unsigned integer types +template +struct __UnsignedIntegerType; + +template<> +struct __UnsignedIntegerType<1> +{ + static const int value = DBUS_TYPE_BYTE; +}; +template<> +struct __UnsignedIntegerType<2> +{ + static const int value = DBUS_TYPE_UINT16; +}; +template<> +struct __UnsignedIntegerType<4> +{ + static const int value = DBUS_TYPE_UINT32; +}; +template<> +struct __UnsignedIntegerType<8> +{ + static const int value = DBUS_TYPE_UINT64; +}; + +// basic types +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_BOOLEAN; +}; + +template<> +struct SimpleType +{ + static const int value = __UnsignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __SignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = + __UnsignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __SignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = + __UnsignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __SignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = + __UnsignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __SignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = + __UnsignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __SignedIntegerType::value; +}; + +template<> +struct SimpleType +{ + static const int value = __UnsignedIntegerType< + sizeof(unsigned long long)>::value; +}; + +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_DOUBLE; +}; + +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_DOUBLE; +}; + +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_STRING; +}; + +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_STRING; +}; + +template<> +struct SimpleType +{ + static const int value = DBUS_TYPE_STRING; +}; + +// STL containers signatures + +// generic array +template +struct ArraySignature +{ + static inline const char* value() + { + static const std::string signature = std::string( + DBUS_TYPE_ARRAY_AS_STRING) + Signature::value(); + return signature.c_str(); + } +}; + +// std::vector +template +struct Signature > : public ArraySignature +{}; + +// std::list +template +struct Signature > : public ArraySignature +{}; + +// std::set +template +struct Signature > : public ArraySignature +{}; + +// std::pair +template +struct Signature > +{ + static inline const char* value() + { + static const std::string signature = std::string( + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING) + + Signature::value() + Signature::value() + + DBUS_DICT_ENTRY_END_CHAR_AS_STRING; + return signature.c_str(); + } +}; + +// std::map +template +struct Signature > : public ArraySignature > +{}; +} // namespace DBus +} // namespace DPL + +#endif // DPL_DBUS_SIGNATURE_H diff --git a/modules/dbus/include/dpl/dbus/dispatcher.h b/modules/dbus/include/dpl/dbus/dispatcher.h new file mode 100644 index 0000000..93e62e6 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/dispatcher.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file dispatcher.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_DISPATCHER_H +#define DPL_DBUS_DISPATCHER_H + +#include + +namespace DPL { +namespace DBus { +class Dispatcher +{ + public: + virtual ~Dispatcher() = 0; + + /** + * Called on method invocation. + * + * @param connection + * @param sender + * @param objectPath + * @param interfaceName + * @param methodName + * @param parameters + * @param invocation + * + * @see GLib DBus documentation. + */ + virtual void onMethodCall(GDBusConnection* connection, + const gchar* sender, + const gchar* objectPath, + const gchar* interfaceName, + const gchar* methodName, + GVariant* parameters, + GDBusMethodInvocation* invocation) = 0; + + /** + * Called on property get. + * + * @param connection + * @param sender + * @param objectPath + * @param interfaceName + * @param propertyName + * @return Porperty value. + * + * @see GLib DBus documentation. + */ + virtual GVariant* onPropertyGet(GDBusConnection* connection, + const gchar* sender, + const gchar* objectPath, + const gchar* interfaceName, + const gchar* propertyName, + GError** error); + + /** + * Called on property set. + * + * @param connection + * @param sender + * @param objectPath + * @param interfaceName + * @param propertyName + * @param value + * @return TRUE if successfully set, FALSE otherwise. + * + * @see GLib DBus documentation. + */ + virtual gboolean onPropertySet(GDBusConnection* connection, + const gchar* sender, + const gchar* objectPath, + const gchar* interfaceName, + const gchar* propertyName, + GVariant* value, + GError** error); +}; +} +} + +#endif // DPL_DBUS_DISPATCHER_H diff --git a/modules/dbus/include/dpl/dbus/exception.h b/modules/dbus/include/dpl/dbus/exception.h new file mode 100644 index 0000000..035d16f --- /dev/null +++ b/modules/dbus/include/dpl/dbus/exception.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file exception.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_EXCEPTION_H +#define DPL_DBUS_EXCEPTION_H + +#include + +namespace DPL { +namespace DBus { +/** + * Thrown when none of the following, more specific exception fit. + */ +DECLARE_EXCEPTION_TYPE(DPL::Exception, Exception) + +/** + * Thrown when trying to perform an operation on a closed connection. + */ +DECLARE_EXCEPTION_TYPE(DBus::Exception, ConnectionClosedException) + +/** + * Thrown when passing invalid argument(s). + */ +DECLARE_EXCEPTION_TYPE(DBus::Exception, InvalidArgumentException) +} +} + +#endif diff --git a/modules/dbus/include/dpl/dbus/glib_util.h b/modules/dbus/include/dpl/dbus/glib_util.h new file mode 100644 index 0000000..13206e3 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/glib_util.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file glib_util.h + * @author Iwanek Tomasz (t.iwanek@samsung.com) + * @version 1.0 + * @brief This file is the definitions of loop controlling utilities + */ +#ifndef GLIB_UTIL_H +#define GLIB_UTIL_H + +//this header wraps glib headers which generates warnings + +#pragma GCC system_header +#include + +#endif // GLIB_UTIL_H diff --git a/modules/dbus/include/dpl/dbus/interface.h b/modules/dbus/include/dpl/dbus/interface.h new file mode 100644 index 0000000..6248dab --- /dev/null +++ b/modules/dbus/include/dpl/dbus/interface.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file interface.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_INTERFACE_H +#define DPL_DBUS_INTERFACE_H + +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +class Interface; +typedef std::shared_ptr InterfacePtr; + +class Interface : private DPL::Noncopyable +{ + public: + /** + * Parses supplied XML string to produce DBus interface descriptions. + * + * @param xmlString XML string to parse. + * @return Interfaces. + * @throw DPL::DBus::Exception If error while parsing occurs. + */ + static std::vector fromXMLString( + const std::string& xmlString); + + public: + ~Interface(); + + /** + * Gets pointers to functions called on method call or property get/set + * request. + * + * @return Pointers to functions. + */ + const GDBusInterfaceVTable* getVTable() const; + + /** + * Gets interface description. + * + * @return Interface description. + */ + GDBusInterfaceInfo* getInfo() const; + + /** + * Sets method/property dispatcher for the interface. + * + * @param dispatcher Method call and property get/set dispatcher. + */ + void setDispatcher(Dispatcher* dispatcher); + + private: + static void onMethodCallFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *methodName, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer data); + + static GVariant* onPropertyGetFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *propertyName, + GError **error, + gpointer data); + + static gboolean onPropertySetFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *propertyName, + GVariant *value, + GError **error, + gpointer data); + + explicit Interface(GDBusInterfaceInfo* info); + + static const GDBusInterfaceVTable m_vTable; + + GDBusInterfaceInfo* m_info; + + Dispatcher* m_dispatcher; +}; +} +} + +#endif // DPL_DBUS_INTERFACE_H diff --git a/modules/dbus/include/dpl/dbus/method_proxy.h b/modules/dbus/include/dpl/dbus/method_proxy.h new file mode 100644 index 0000000..19c3b90 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/method_proxy.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file method_proxy.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_METHOD_PROXY_H +#define DPL_DBUS_METHOD_PROXY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +class ObjectProxy; + +/** + * Represents a remote method. + */ +template +class MethodProxy +{ + public: + ~MethodProxy() + { + g_object_unref(m_connection); + } + + /** + * Invokes remote method. + * + * @param args Input arguments for remote method. + * @return Value returned by remote method. + * @throw DBus::InvalidArgumentException If invalid argument(s) supplied. + * @throw DBus::ConnectionClosedException If connection is closed. + * @throw DBus::Exception If some other error occurs. + */ + Result operator()(const Args& ... args) + { + return invoke(args ...); + } + + private: + friend class ObjectProxy; + + MethodProxy(GDBusConnection* connection, + const std::string& serviceName, + const std::string& objectPath, + const std::string& interfaceName, + const std::string& methodName) : + m_connection(connection), + m_serviceName(serviceName), + m_objectPath(objectPath), + m_interfaceName(interfaceName), + m_methodName(methodName) + { + Assert(m_connection && "Connection is not set."); + + g_object_ref(m_connection); + } + + /** + * @remarks Making it a template with parameter set by default to class + * template parameter to overload on return type by utilizing + * the SFINAE concept. + */ + template + typename std::enable_if::value, R>::type + invoke(const Args& ... args) + { + GVariant* parameters = serialize(args ...); + + GVariant* invokeResult = invokeSync(parameters); + + R result; + + ServerDeserialization::deserialize(invokeResult, &result); + + g_variant_unref(invokeResult); + + return result; + } + + /** + * @remarks Void return type overload. + */ + template + typename std::enable_if::value>::type + invoke(const Args& ... args) + { + GVariant* parameters = serialize(args ...); + + GVariant* invokeResult = invokeSync(parameters); + + g_variant_unref(invokeResult); + } + + /** + * @remarks ArgsM... are the same as Args...; it has been made a template + * to make overloading/specialization possible. + */ + template + GVariant* serialize(ArgsM && ... args) + { + return ServerSerialization::serialize(std::forward(args) ...); + } + + /** + * @remarks Specialization for zero-argument functions. + */ + GVariant* serialize() + { + return NULL; + } + + /** + * Calls remote method over DBus. + * + * @param parameters Input parameters for the remote method. + * @return Result returned by the remote method. + * @throw DBus::InvalidArgumentException If invalid argument(s) supplied. + * @throw DBus::ConnectionClosedException If connection is closed. + * @throw DBus::Exception If some other error occurs. + */ + GVariant* invokeSync(GVariant* parameters) + { + GError* error = NULL; + + LogPedantic( + "Invoking method: " << m_interfaceName << "." << m_methodName); + GVariant* result = g_dbus_connection_call_sync(m_connection, + m_serviceName.c_str(), + m_objectPath.c_str(), + m_interfaceName.c_str(), + m_methodName.c_str(), + parameters, + G_VARIANT_TYPE_TUPLE, + G_DBUS_CALL_FLAGS_NONE, + DBUS_SYNC_CALL_TIMEOUT, + NULL, + &error); + if (NULL == result) { + std::ostringstream oss; + oss << "Error while invoking: " + << m_interfaceName << "." << m_methodName + << " <" << error->message << ">"; + std::string message = oss.str(); + + gint code = error->code; + + g_error_free(error); + + switch (code) { + case G_IO_ERROR_INVALID_ARGUMENT: + ThrowMsg(DBus::InvalidArgumentException, message); + case G_IO_ERROR_CLOSED: + ThrowMsg(DBus::ConnectionClosedException, message); + default: + ThrowMsg(DBus::Exception, message); + } + } + + return result; + } + + /** + * Default timeout for synchronous method call. + * + * @see GIO::GDBusConnection::g_dbus_connection_call_sync() for details. + */ + static const gint DBUS_SYNC_CALL_TIMEOUT = -1; + + GDBusConnection* m_connection; + std::string m_serviceName; + std::string m_objectPath; + std::string m_interfaceName; + std::string m_methodName; +}; + +/** + * Smart pointer for MethodProxy objects. + */ +template +class MethodProxyPtr +{ + public: + explicit MethodProxyPtr(MethodProxy* method = NULL) : + m_method(method) + {} + + Result operator()(const Args& ... args) const + { + Assert(NULL != m_method.get() && "Method not set."); + + return (*m_method)(args ...); + } + + private: + std::shared_ptr > m_method; +}; +} +} + +#endif diff --git a/modules/dbus/include/dpl/dbus/object.h b/modules/dbus/include/dpl/dbus/object.h new file mode 100644 index 0000000..191464c --- /dev/null +++ b/modules/dbus/include/dpl/dbus/object.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file object.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_OBJECT_H +#define DPL_DBUS_OBJECT_H + +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +class Object; +typedef std::shared_ptr ObjectPtr; + +class Object +{ + public: + /** + * Creates an object. + * + * @param path Object's path. + * @param interface Interface the object supports. + * @return Object shared pointer. + */ + static ObjectPtr create(const std::string& path, + const InterfacePtr& interface); + + /** + * Gets object's path. + * + * @return Object's path. + */ + std::string getPath() const; + + /** + * Gets object's interface. + * + * @return Object's interface. + */ + InterfacePtr getInterface() const; + + private: + Object(const std::string& path, const InterfacePtr& interface); + + std::string m_path; + InterfacePtr m_interface; +}; +} +} + +#endif // WRT_SRC_DBUS_OBJECT_H diff --git a/modules/dbus/include/dpl/dbus/object_proxy.h b/modules/dbus/include/dpl/dbus/object_proxy.h new file mode 100644 index 0000000..17764f1 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/object_proxy.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file object_proxy.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_OBJECT_PROXY_H +#define DPL_DBUS_OBJECT_PROXY_H + +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +class Connection; + +/** + * Represents a remote object attached to a DBus service. + */ +class ObjectProxy +{ + public: + ~ObjectProxy(); + + /** + * Creates method proxy object. + * + * The object is used to call remote methods. + * + * @param interface Name of the DBus interface. + * @param name Name of the method to call. + * @return Proxy to remote method. + * @throw DBus::ConnectionClosedException If connection is closed. + */ + template + MethodProxyPtr createMethodProxy( + const std::string& interface, + const std::string& name) + { + if (g_dbus_connection_is_closed(m_connection)) { + ThrowMsg(DBus::ConnectionClosedException, "Connection closed."); + } + + return MethodProxyPtr( + new MethodProxy(m_connection, + m_serviceName, + m_objectPath, + interface, + name)); + } + + private: + friend class Connection; + + ObjectProxy(GDBusConnection* connection, + const std::string& serviceName, + const std::string& objectPath); + + GDBusConnection* m_connection; + std::string m_serviceName; + std::string m_objectPath; +}; +} +} + +#endif diff --git a/modules/dbus/include/dpl/dbus/server.h b/modules/dbus/include/dpl/dbus/server.h new file mode 100644 index 0000000..795a757 --- /dev/null +++ b/modules/dbus/include/dpl/dbus/server.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file server.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_DBUS_SERVER_H +#define DPL_DBUS_SERVER_H + +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +namespace ServerEvents { +/** + * Emitted when new connection is accepted. + * + * Arg0 Accepted connection. + * + * @remarks If this event is processed on separate thread than that thread + * should run GLib main loop if one wants to e.g. register DBus + * objects during this event processing. + */ +DECLARE_GENERIC_EVENT_1(NewConnectionEvent, ConnectionPtr) +} + +class Server; +typedef std::shared_ptr ServerPtr; + +/** + * Class acting as a server for peer to peer connections over DBus. + */ +class Server : public DPL::Event::EventSupport +{ + public: + /** + * Creates server. + * + * @param address Address the server should listen on. + * @return Server. + */ + static ServerPtr create(const std::string& address); + + ~Server(); + + /** + * Starts the server. + */ + void start(); + + /** + * Stops the server. + */ + void stop(); + + protected: + explicit Server(GDBusServer* server); + + private: + static gboolean onNewConnection(GDBusServer* server, + GDBusConnection* connection, + gpointer data); + + GDBusServer* m_server; +}; +} +} + +#endif // DPL_DBUS_SERVER_H diff --git a/modules/dbus/src/connection.cpp b/modules/dbus/src/connection.cpp new file mode 100644 index 0000000..9c3b6ba --- /dev/null +++ b/modules/dbus/src/connection.cpp @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file connection.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +ConnectionPtr Connection::sessionBus() +{ + return connectTo(G_BUS_TYPE_SESSION); +} + +ConnectionPtr Connection::systemBus() +{ + return connectTo(G_BUS_TYPE_SYSTEM); +} + +ConnectionPtr Connection::connectTo(GBusType busType) +{ + GError* error = NULL; + + GDBusConnection* connection = g_bus_get_sync(busType, + NULL, + &error); + if (NULL == connection) { + std::string message; + if (NULL != error) { + message = error->message; + g_error_free(error); + } + ThrowMsg(DBus::Exception, + "Couldn't connect to bus: " << message); + } + + g_dbus_connection_set_exit_on_close(connection, FALSE); + + return ConnectionPtr(new Connection(connection)); +} + +ConnectionPtr Connection::connectTo(const std::string& address) +{ + GError* error = NULL; + + GDBusConnection* connection = g_dbus_connection_new_for_address_sync( + address.c_str(), + G_DBUS_CONNECTION_FLAGS_NONE, + NULL, + NULL, + &error); + if (NULL == connection) { + std::string message; + if (NULL != error) { + message = error->message; + g_error_free(error); + } + ThrowMsg(DBus::Exception, + "Couldn't connect to " << address << ": " << message); + } + + return ConnectionPtr(new Connection(connection)); +} + +Connection::Connection(GDBusConnection* connection) : + m_connection(connection) +{ + g_signal_connect(m_connection, + "closed", + G_CALLBACK(onConnectionClosed), + this); +} + +Connection::~Connection() +{ + std::for_each(m_registeredServices.begin(), + m_registeredServices.end(), + [] (const RegisteredServices::value_type & value) + { + g_bus_unown_name(value.second); + }); + + std::for_each(m_registeredObjects.begin(), + m_registeredObjects.end(), + [this] (const RegisteredObjects::value_type & value) + { + g_dbus_connection_unregister_object( + m_connection, + value.second.registrationId); + }); + + if (!g_dbus_connection_is_closed(m_connection)) { + GError* error = NULL; + + if (FALSE == + g_dbus_connection_flush_sync(m_connection, NULL, &error)) + { + LogPedantic("Could not flush the connection" + << " <" << error->message << ">"); + g_error_free(error); + } + } + + g_object_unref(m_connection); +} + +void Connection::registerService(const std::string& serviceName) +{ + guint regId = g_bus_own_name_on_connection(m_connection, + serviceName.c_str(), + G_BUS_NAME_OWNER_FLAGS_NONE, + onServiceNameAcquired, + onServiceNameLost, + this, + NULL); + if (0 >= regId) { + ThrowMsg(DBus::Exception, "Error while registering service."); + } + + m_registeredServices.insert(RegisteredServices::value_type(serviceName, + regId)); +} + +void Connection::unregisterService(const std::string& serviceName) +{ + auto it = m_registeredServices.find(serviceName); + if (m_registeredServices.end() == it) { + ThrowMsg(DBus::Exception, "Service not registered."); + } + + g_bus_unown_name(it->second); + + m_registeredServices.erase(it); +} + +void Connection::registerObject(const ObjectPtr& object) +{ + GError* error = NULL; + + guint regId = g_dbus_connection_register_object( + m_connection, + object->getPath().c_str(), + object->getInterface()->getInfo(), + object->getInterface()->getVTable(), + // TODO This is ugly, fix this! + object->getInterface().get(), + NULL, + &error); + if (0 == regId) { + std::string message; + if (NULL != error) { + message = error->message; + LogPedantic(error->message << " " << error->code); + g_error_free(error); + } + ThrowMsg(DBus::Exception, "Error while registering an object: " + << message); + } + + m_registeredObjects.insert(RegisteredObjects::value_type( + object->getPath(), + ObjectRegistration(regId, object))); +} + +void Connection::unregisterObject(const std::string& objectPath) +{ + auto it = m_registeredObjects.find(objectPath); + if (m_registeredObjects.end() == it) { + ThrowMsg(DBus::Exception, "Object not registered."); + } + + gboolean result = g_dbus_connection_unregister_object( + m_connection, + it->second.registrationId); + if (FALSE == result) { + ThrowMsg(DBus::Exception, "Unregistering object failed."); + } + m_registeredObjects.erase(it); +} + +ObjectProxyPtr Connection::createObjectProxy(const std::string& serviceName, + const std::string& objectPath) +{ + if (g_dbus_connection_is_closed(m_connection)) { + ThrowMsg(DBus::ConnectionClosedException, "Connection closed."); + } + + return ObjectProxyPtr( + new ObjectProxy(m_connection, serviceName, objectPath)); +} + +void Connection::onServiceNameAcquired(GDBusConnection* /*connection*/, + const gchar* serviceName, + gpointer data) +{ + AssertMsg(data, "Connection should not be NULL"); + + Connection* self = static_cast(data); + + LogPedantic("Emitting service name acquired event: " << serviceName); + + ConnectionEvents::ServiceNameAcquiredEvent event(serviceName); + self->DPL::Event::EventSupport + :: + EmitEvent(event, DPL::Event::EmitMode::Queued); +} + +void Connection::onServiceNameLost(GDBusConnection* /*connection*/, + const gchar* serviceName, + gpointer data) +{ + AssertMsg(data, "Connection should not be NULL"); + + Connection* self = static_cast(data); + + LogPedantic("Emitting service name lost event: " << serviceName); + + ConnectionEvents::ServiceNameLostEvent event(serviceName); + self->DPL::Event::EventSupport:: + EmitEvent(event, DPL::Event::EmitMode::Queued); +} + +void Connection::onConnectionClosed(GDBusConnection* /*connection*/, + gboolean peerVanished, + GError* error, + gpointer data) +{ + AssertMsg(NULL != data, "Connection cannot be NULL"); + + Connection* self = static_cast(data); + + if ((NULL == error) && (FALSE == peerVanished)) { + // Connection closed by this. + } else if (NULL != error) { + std::string message = error->message; + + g_error_free(error); + + if (TRUE == peerVanished) { + // Connection closed by remote host. + ConnectionEvents::ConnectionBrokenEvent event(message); + self->DPL::Event::EventSupport:: + EmitEvent(event, DPL::Event::EmitMode::Queued); + } else { + // Invalid or malformed data on connection. + ConnectionEvents::ConnectionInvalidEvent event(message); + self->DPL::Event::EventSupport:: + EmitEvent(event, DPL::Event::EmitMode::Queued); + } + } +} +} +} diff --git a/modules/dbus/src/dispatcher.cpp b/modules/dbus/src/dispatcher.cpp new file mode 100644 index 0000000..d83a22a --- /dev/null +++ b/modules/dbus/src/dispatcher.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file dispatcher.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ +#include +#include + +namespace DPL { +namespace DBus { +Dispatcher::~Dispatcher() { } + +GVariant* Dispatcher::onPropertyGet(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* /*interfaceName*/, + const gchar* /*propertyName*/, + GError** /*error*/) +{ + return NULL; +} + +gboolean Dispatcher::onPropertySet(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* /*interfaceName*/, + const gchar* /*propertyName*/, + GVariant* /*value*/, + GError** /*error*/) +{ + return false; +} +} +} diff --git a/modules/dbus/src/interface.cpp b/modules/dbus/src/interface.cpp new file mode 100644 index 0000000..b449e7c --- /dev/null +++ b/modules/dbus/src/interface.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file interface.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +const GDBusInterfaceVTable Interface::m_vTable = { + Interface::onMethodCallFunc, + Interface::onPropertyGetFunc, + Interface::onPropertySetFunc, + { 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +std::vector Interface::fromXMLString(const std::string& xmlString) +{ + GError* error = NULL; + + GDBusNodeInfo* nodeInfo = g_dbus_node_info_new_for_xml(xmlString.c_str(), + &error); + if (NULL == nodeInfo) { + std::string message; + if (NULL != error) { + message = error->message; + g_error_free(error); + } + ThrowMsg(DPL::DBus::Exception, + "Error parsing node info <" << message << ">"); + } + + std::vector result; + + GDBusInterfaceInfo** interface = nodeInfo->interfaces; + while (NULL != *interface) { + result.push_back(InterfacePtr(new Interface(*interface))); + ++interface; + } + + g_dbus_node_info_unref(nodeInfo); + + return result; +} + +Interface::Interface(GDBusInterfaceInfo* info) : + m_info(info) +{ + g_dbus_interface_info_ref(m_info); +} + +Interface::~Interface() +{ + g_dbus_interface_info_unref(m_info); +} + +const GDBusInterfaceVTable* Interface::getVTable() const +{ + return &m_vTable; +} + +GDBusInterfaceInfo* Interface::getInfo() const +{ + return m_info; +} + +void Interface::setDispatcher(Dispatcher* dispatcher) +{ + m_dispatcher = dispatcher; +} + +void Interface::onMethodCallFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *methodName, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer data) +{ + AssertMsg(NULL != data, "Interface cannot be NULL."); + Interface* self = static_cast(data); + + // TODO Verify interface name. + + if (NULL != self->m_dispatcher) { + try { + self->m_dispatcher->onMethodCall(connection, + sender, + objectPath, + interfaceName, + methodName, + parameters, + invocation); + } catch (const DPL::Exception& /*ex*/) { + // TODO Support for errors. + } + } +} + +GVariant* Interface::onPropertyGetFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *propertyName, + GError **error, + gpointer data) +{ + AssertMsg(NULL != data, "Interface cannot be NULL."); + Interface* self = static_cast(data); + + // TODO Verify interface name. + + if (NULL != self->m_dispatcher) { + try { + // TODO Check if NULL is returned, if so set error variable. + return self->m_dispatcher->onPropertyGet(connection, + sender, + objectPath, + interfaceName, + propertyName, + error); + } catch (const DPL::Exception& /*ex*/) { + // TODO Support for errors. + } + } + + // TODO Set error. + + return NULL; +} + +gboolean Interface::onPropertySetFunc(GDBusConnection *connection, + const gchar *sender, + const gchar *objectPath, + const gchar *interfaceName, + const gchar *propertyName, + GVariant *value, + GError **error, + gpointer data) +{ + AssertMsg(NULL != data, "Interface cannot be NULL."); + Interface* self = static_cast(data); + + // TODO Verify interface name. + + if (NULL != self->m_dispatcher) { + try { + return self->m_dispatcher->onPropertySet(connection, + sender, + objectPath, + interfaceName, + propertyName, + value, + error); + } catch (const DPL::Exception& /*ex*/) { + // TODO Support for errors. + } + } + + // TODO Set error. + + return false; +} +} +} diff --git a/modules/dbus/src/object.cpp b/modules/dbus/src/object.cpp new file mode 100644 index 0000000..a66796d --- /dev/null +++ b/modules/dbus/src/object.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file object.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ +#include +#include + +namespace DPL { +namespace DBus { +ObjectPtr Object::create(const std::string& path, const InterfacePtr& interface) +{ + return ObjectPtr(new Object(path, interface)); +} + +std::string Object::getPath() const +{ + return m_path; +} + +InterfacePtr Object::getInterface() const +{ + return m_interface; +} + +Object::Object(const std::string& path, const InterfacePtr& interface) : + m_path(path), + m_interface(interface) +{} +} +} \ No newline at end of file diff --git a/modules/dbus/src/object_proxy.cpp b/modules/dbus/src/object_proxy.cpp new file mode 100644 index 0000000..9b15bb7 --- /dev/null +++ b/modules/dbus/src/object_proxy.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file object_proxy.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ +#include +#include + +namespace DPL { +namespace DBus { +ObjectProxy::ObjectProxy(GDBusConnection* connection, + const std::string& serviceName, + const std::string& objectPath) : + m_connection(connection), + m_serviceName(serviceName), + m_objectPath(objectPath) +{ + g_object_ref(m_connection); +} + +ObjectProxy::~ObjectProxy() +{ + g_object_unref(m_connection); +} +} +} \ No newline at end of file diff --git a/modules/dbus/src/server.cpp b/modules/dbus/src/server.cpp new file mode 100644 index 0000000..41c6962 --- /dev/null +++ b/modules/dbus/src/server.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file server.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief + */ +#include +#include +#include +#include + +namespace DPL { +namespace DBus { +ServerPtr Server::create(const std::string& address) +{ + GError* error = NULL; + + int flags = G_DBUS_SERVER_FLAGS_NONE | + G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; + + gchar* serverId = g_dbus_generate_guid(); + + GDBusServer* server = g_dbus_server_new_sync( + address.c_str(), + static_cast(flags), + serverId, + NULL, + NULL, + &error); + g_free(serverId); + + if (NULL == server) { + std::string message; + if (NULL != error) { + message = error->message; + g_error_free(error); + } + + ThrowMsg(DPL::Exception, "Error on server creation: " << message); + } + + return ServerPtr(new Server(server)); +} + +Server::Server(GDBusServer* server) : + m_server(server) +{} + +Server::~Server() +{ + if (g_dbus_server_is_active(m_server)) { + stop(); + } + g_object_unref(m_server); +} + +void Server::start() +{ + AssertMsg(!g_dbus_server_is_active(m_server), "Server already started."); + + g_dbus_server_start(m_server); + + g_signal_connect(m_server, + "new-connection", + G_CALLBACK(onNewConnection), + this); + + LogDebug("Server started at: " + << g_dbus_server_get_client_address(m_server)); +} + +void Server::stop() +{ + AssertMsg(g_dbus_server_is_active(m_server), "Server not started."); + + g_dbus_server_stop(m_server); +} + +gboolean Server::onNewConnection(GDBusServer* /*server*/, + GDBusConnection* connection, + gpointer data) +{ + AssertMsg(NULL != data, "User data cannot be NULL."); + + Server* self = static_cast(data); + + ServerEvents::NewConnectionEvent event( + ConnectionPtr(new Connection(connection))); + + LogDebug("Emitting new connection event"); + // TODO Blocking to allow object registration before any DBus messages are + // processed. + self->DPL::Event::EventSupport:: + EmitEvent(event, DPL::Event::EmitMode::Blocking); + + return TRUE; +} +} +} diff --git a/modules/event/config.cmake b/modules/event/config.cmake new file mode 100644 index 0000000..313b6a8 --- /dev/null +++ b/modules/event/config.cmake @@ -0,0 +1,55 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_EVENT_SOURCES + ${PROJECT_SOURCE_DIR}/modules/event/src/abstract_event_call.cpp + ${PROJECT_SOURCE_DIR}/modules/event/src/abstract_event_dispatcher.cpp + ${PROJECT_SOURCE_DIR}/modules/event/src/controller.cpp + ${PROJECT_SOURCE_DIR}/modules/event/src/event_listener.cpp + ${PROJECT_SOURCE_DIR}/modules/event/src/event_support.cpp + ${PROJECT_SOURCE_DIR}/modules/event/src/generic_event_call.cpp + ${PROJECT_SOURCE_DIR}/modules/event/src/main_event_dispatcher.cpp + ${PROJECT_SOURCE_DIR}/modules/event/src/thread_event_dispatcher.cpp + ${PROJECT_SOURCE_DIR}/modules/event/src/inter_context_delegate.cpp + ${PROJECT_SOURCE_DIR}/modules/event/src/model.cpp + PARENT_SCOPE +) + +SET(DPL_EVENT_HEADERS + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/abstract_event_call.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/abstract_event_dispatcher.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/controller.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/event_listener.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/event_support.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/generic_event_call.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/main_event_dispatcher.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/thread_event_dispatcher.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/inter_context_delegate.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/model.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/property.h + ${PROJECT_SOURCE_DIR}/modules/event/include/dpl/event/model_bind_to_dao.h + PARENT_SCOPE +) + +SET(DPL_EVENT_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/event/include/ + PARENT_SCOPE +) diff --git a/modules/event/include/dpl/event/abstract_event_call.h b/modules/event/include/dpl/event/abstract_event_call.h new file mode 100644 index 0000000..db1bea4 --- /dev/null +++ b/modules/event/include/dpl/event/abstract_event_call.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_event_call.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract event call + */ +#ifndef DPL_ABSTRACT_EVENT_CALL_H +#define DPL_ABSTRACT_EVENT_CALL_H + +#include + +namespace DPL { +namespace Event { +class AbstractEventCall : + private Noncopyable +{ + public: + /** + * Constructor + */ + explicit AbstractEventCall(); + + /** + * Destructor + */ + virtual ~AbstractEventCall(); + + /** + * Call abstract event call + */ + virtual void Call() = 0; +}; +} +} // namespace DPL + +#endif // DPL_ABSTRACT_EVENT_CALL_H diff --git a/modules/event/include/dpl/event/abstract_event_dispatcher.h b/modules/event/include/dpl/event/abstract_event_dispatcher.h new file mode 100644 index 0000000..f5caa56 --- /dev/null +++ b/modules/event/include/dpl/event/abstract_event_dispatcher.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_event_dispatcher.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract event + * dispatcher + */ +#ifndef DPL_ABSTRACT_EVENT_DISPATCHER_H +#define DPL_ABSTRACT_EVENT_DISPATCHER_H + +#include +#include + +namespace DPL { +namespace Event { +class AbstractEventDispatcher : + private Noncopyable +{ + public: + /** + * Constructor + */ + explicit AbstractEventDispatcher(); + + /** + * Destructor + */ + virtual ~AbstractEventDispatcher(); + + /** + * Add abstract event call to abstract event dispatcher + * + * @param[in] abstractEventCall Pointer to abstract event call to add + * @return none + */ + virtual void AddEventCall(AbstractEventCall *abstractEventCall) = 0; + + /** + * Add abstract timed event call to abstract event dispatcher + * + * @param[in] abstractEventCall Pointer to abstract event call to add + * @param[in] dueTime Due time for timed event in seconds + * @return none + */ + virtual void AddTimedEventCall(AbstractEventCall *abstractEventCall, + double dueTime) = 0; +}; +} +} // namespace DPL + +#endif // DPL_ABSTRACT_EVENT_DISPATCHER_H diff --git a/modules/event/include/dpl/event/controller.h b/modules/event/include/dpl/event/controller.h new file mode 100644 index 0000000..1b14632 --- /dev/null +++ b/modules/event/include/dpl/event/controller.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file controller.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC controller + */ +#ifndef DPL_CONTROLLER_H +#define DPL_CONTROLLER_H + +#include +#include +#include +#include +#include + +namespace DPL { +namespace Event { +template +class ControllerEventHandler : + public EventListener, + private EventSupport +{ + private: + bool m_touched; + + public: + ControllerEventHandler() : + m_touched(false) + { + EventSupport::AddListener(this); + } + + virtual ~ControllerEventHandler() + { + EventSupport::RemoveListener(this); + } + + void PostEvent(const EventType &event) + { + Assert( + m_touched && + "Default context not inherited. Call Touch() to inherit one."); + EventSupport::EmitEvent(event, EmitMode::Queued); + } + + void PostTimedEvent(const EventType &event, double dueTime) + { + Assert( + m_touched && + "Default context not inherited. Call Touch() to inherit one."); + EventSupport::EmitEvent(event, EmitMode::Deffered, dueTime); + } + + void PostSyncEvent(const EventType &event) + { + Assert( + m_touched && + "Default context not inherited. Call Touch() to inherit one."); + + // Check calling context + EventSupport::EmitEvent(event, EmitMode::Blocking); + } + + void SwitchToThread(Thread *thread) + { + Assert( + m_touched && + "Default context not inherited. Call Touch() to inherit one."); + EventSupport::SwitchListenerToThread(this, thread); + } + + void Touch() + { + m_touched = true; + EventSupport::SwitchListenerToThread( + this, + Thread:: + GetCurrentThread()); + } +}; + +template +class Controller : + public Controller, + public ControllerEventHandler +{ + public: + typedef typename EventTypeList::Head EventType; + + public: + Controller() + {} + + virtual ~Controller() + {} + + virtual void SwitchToThread(Thread *thread) + { + ControllerEventHandler::SwitchToThread(thread); + Controller::SwitchToThread(thread); + } + + virtual void Touch() + { + ControllerEventHandler::Touch(); + Controller::Touch(); + } +}; + +template<> +class Controller::Type> +{ + public: + Controller() + {} + + virtual ~Controller() + {} + + virtual void SwitchToThread(Thread *thread) + { + (void)thread; + } + + virtual void Touch() + {} +}; +} +} // namespace DPL + +// Utilities +#define CONTROLLER_POST_EVENT(Name, \ + EventArg) Name##Singleton::Instance().DPL::Event \ + ::ControllerEventHandler< \ + __typeof__ EventArg>::PostEvent(EventArg) +#define CONTROLLER_POST_TIMED_EVENT(Name, EventArg, \ + DueTime) Name##Singleton::Instance().DPL:: \ + Event::ControllerEventHandler< \ + __typeof__ EventArg>::PostTimedEvent(EventArg, DueTime) +#define CONTROLLER_POST_SYNC_EVENT(Name, \ + EventArg) Name##Singleton::Instance().DPL:: \ + Event::ControllerEventHandler< \ + __typeof__ EventArg>::PostSyncEvent(EventArg) + +#endif // DPL_CONTROLLER_H diff --git a/modules/event/include/dpl/event/event_listener.h b/modules/event/include/dpl/event/event_listener.h new file mode 100644 index 0000000..27fdbec --- /dev/null +++ b/modules/event/include/dpl/event/event_listener.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file event_listener.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC event listener + */ +#ifndef DPL_EVENT_LISTENER_H +#define DPL_EVENT_LISTENER_H + +#include + +namespace DPL { +namespace Event { +template +class EventListener : + private Noncopyable +{ + public: + EventListener() + {} + + virtual ~EventListener() + {} + + virtual void OnEventReceived(const EventType &event) = 0; +}; +} +} // namespace DPL + +#endif // DPL_EVENT_LISTENER_H diff --git a/modules/event/include/dpl/event/event_support.h b/modules/event/include/dpl/event/event_support.h new file mode 100644 index 0000000..ac58480 --- /dev/null +++ b/modules/event/include/dpl/event/event_support.h @@ -0,0 +1,772 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file event_support.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC event support + */ +#ifndef DPL_EVENT_SUPPORT_H +#define DPL_EVENT_SUPPORT_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Event { +namespace EmitMode { +enum Type +{ + Auto, ///< If calling thread is the same as receiver's use + ///< direct call, otherwise call is queued + + Queued, ///< Call is always queued + + Blocking, ///< If calling thread is the same as receiver's use + ///< direct call, otherwise call is queued and blocking + + Deffered ///< Call is always queued for a period of time +}; +} // namespace EmitMode + +template +class EventSupport : + private Noncopyable +{ + public: + typedef EventSupport EventSupportType; + + typedef EventListener EventListenerType; + + typedef void DelegateSignature(const EventType&); + typedef std::function DelegateType; + + class EventSupportData; // Forward declaration + typedef EventSupportData *EventSupportDataPtr; + + private: + typedef typename GenericEventCall:: + template Rebind:: + Other GenericEventCallType; + + // Event listener list + typedef std::map EventListenerList; + EventListenerList m_eventListenerList; + + struct DelegateCompare + { + typedef typename std::add_pointer::type + DelegateSignaturePtr; + + bool operator()(const DelegateType& a, const DelegateType& b) const + { + return comparer(a.template target(), + b.template target()); + } + + const std::less comparer; + }; + + // Delegate list + typedef std::map DelegateList; + DelegateList m_delegateList; + + // Event support operation mutex + Mutex m_listenerDelegateMutex; + + // Dedicated instance of thread event dispatcher + ThreadEventDispatcher m_threadEventDispatcher; + + // Guard destruction of event support in event handler + Atomic m_guardedCallInProgress; + + // Events created by this support + typedef std::list EventCallList; + EventCallList m_eventsList; + + // Events list mutex + Mutex m_eventListMutex; + + public: + class EventSupportData + { + private: + typedef void (EventSupportType::*ReceiveAbstractEventCallMethod)( + const EventType &event, + EventListenerType *eventListener, + DelegateType delegate, + WaitableEvent *synchronization); + + EventSupportType *m_eventSupport; + ReceiveAbstractEventCallMethod m_method; + typename EventCallList::iterator m_iterator; + + //TODO: Add dispatcher iterator to remove events from + // framework/thread's event queue + WaitableEvent *m_synchronization; + + Mutex m_dataMutex; + + public: + EventSupportData(EventSupportType *support, + ReceiveAbstractEventCallMethod method, + WaitableEvent *synchronization) : + m_eventSupport(support), + m_method(method), + m_synchronization(synchronization) + {} + + ~EventSupportData() + { + Mutex::ScopedLock lock(&m_dataMutex); + + if (!m_eventSupport) { + LogPedantic("EventSupport for this call does not exist"); + return; + } + + m_eventSupport->RemoveEventCall(m_iterator); + } + + // TODO: Make private and make EventSupport friend + void SetIterator(typename EventCallList::iterator iter) + { + m_iterator = iter; + } + + // This method at the end destroys this as it will not be used anymore + void CallAndDestroy(const EventType &event, + EventListenerType *listener, + DelegateType delegate) + { + { + Mutex::ScopedLock lock(&m_dataMutex); + + if (m_eventSupport != NULL) { + (*m_eventSupport.*m_method)(event, + listener, + delegate, + m_synchronization); + } else { + LogPedantic("EventSupport for this call does not " + "exist anymore. Ignored."); + } + + // releasing mutex lock + } + + // EventSupportData object is no more used. + // It can be safely destroyed now. + delete this; + } + + void Reset() + { + LogPedantic("Reseting my EventSupport"); + + Mutex::ScopedLock lock(&m_dataMutex); + m_eventSupport = NULL; + } + }; + + private: + GenericEventCallType *RegisterEventCall(const EventType &event, + EventListenerType *eventListener, + DelegateType delegate, + WaitableEvent *waitableEvent) + { + LogPedantic("Create and Register EventCall in EventSupport"); + + Mutex::ScopedLock lock(&m_eventListMutex); + + EventSupportDataPtr supportData = + new EventSupportData( + this, + &EventSupportType::ReceiveAbstractEventCall, + waitableEvent); + + GenericEventCallType *eventCall = + new GenericEventCallType(supportData, eventListener, + delegate, event); + + typename EventCallList::iterator eventCallIter = + m_eventsList.insert(m_eventsList.end(), eventCall); + + supportData->SetIterator(eventCallIter); + + return eventCall; + } + + void RemoveEventCall(typename EventCallList::iterator eventIterator) + { + Mutex::ScopedLock lock(&m_eventListMutex); + + LogPedantic("Removing event call from EventSupport"); + + m_eventsList.erase(eventIterator); + } + + // Note: Reentrant metod + void GuardedEventCall(const EventType &event, + EventListenerType *eventListener) + { + LogPedantic("Guarded event listener call..."); + + ++m_guardedCallInProgress; + + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + eventListener->OnEventReceived(event); + } + UNHANDLED_EXCEPTION_HANDLER_END + + -- m_guardedCallInProgress; + + LogPedantic("Guarded event listener finished"); + } + + // Note: Reentrant metod + void GuardedEventCall(const EventType &event, + DelegateType delegate) + { + LogPedantic("Guarded delegate call..."); + + ++m_guardedCallInProgress; + + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + delegate(event); + } + UNHANDLED_EXCEPTION_HANDLER_END + + -- m_guardedCallInProgress; + + LogPedantic("Guarded delegate call finished"); + } + + void ReceiveAbstractEventCall(const EventType &event, + EventListenerType *eventListener, + DelegateType delegate, + WaitableEvent *synchronization) + { + LogPedantic("Received abstract event call method"); + + Thread *targetThread; + + // Listener might have been removed, ensure that it still exits + if (eventListener != NULL) { + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + typename EventListenerList::iterator iterator = + m_eventListenerList.find(eventListener); + + if (iterator == m_eventListenerList.end()) { + LogPedantic("Abstract event call listener disappeared." + "Event ignored."); + + // Even though, synchronize caller if needed + if (synchronization != NULL) { + synchronization->Signal(); + } + + return; + } + + // Get target thread id + targetThread = iterator->second; + } else { + // Delegate might have been removed, ensure that it still exits + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + typename DelegateList::iterator iterator = + m_delegateList.find(delegate); + + if (iterator == m_delegateList.end()) { + LogPedantic("Abstract event call delegate disappeared." + "Event ignored."); + + // Even though, synchronize caller if needed + if (synchronization != NULL) { + synchronization->Signal(); + } + + return; + } + + // Get target thread id + targetThread = iterator->second; + } + + // Ensure that we are now in proper thread now + if (targetThread != Thread::GetCurrentThread()) { + LogPedantic("Detected event dispatching ping-pong scenario"); + + // Retry if it was not synchronized + if (synchronization == NULL) { + // Cheat with event delivery + EmitEvent(event, EmitMode::Queued); + + LogPedantic("Ping-Pong: Resent as queued event"); + } else { + // There is a problem + // Developer did something nasty, and we will not clean up his + // mess + synchronization->Signal(); + + LogPedantic("### Ping-Pong: Failed to deliver synchronized" + "event in ping-pong scenario!"); + } + + return; + } + + // Guard listener code for exceptions + if (eventListener != NULL) { + GuardedEventCall(event, eventListener); + } else { + GuardedEventCall(event, delegate); + } + + // Release caller if synchronizing + if (synchronization != NULL) { + synchronization->Signal(); + } + } + + protected: + void EmitEvent(const EventType &event, + EmitMode::Type mode = EmitMode::Queued, + double dueTime = 0.0) + { + // Emit event, and retrieve later in current context to dispatch + std::unique_ptr lock( + new Mutex::ScopedLock(&m_listenerDelegateMutex)); + + // Show some info + switch (mode) { + case EmitMode::Auto: + LogPedantic("Emitting AUTO event..."); + break; + + case EmitMode::Queued: + LogPedantic("Emitting QUEUED event..."); + break; + + case EmitMode::Blocking: + LogPedantic("Emitting BLOCKING event..."); + break; + + case EmitMode::Deffered: + LogPedantic("Emitting DEFFERED event..."); + break; + + default: + break; + } + + // In some configurations there is a barrier + std::vector synchronizationBarrier; + + // Emit to all listeners + FOREACH(iterator, m_eventListenerList) + { + // Switch to proper dispatcher and emit event + AbstractEventDispatcher *dispatcher = NULL; + + if (iterator->second == NULL) { + // Send to main thread + LogPedantic("Sending event to main dispatcher"); + dispatcher = &GetMainEventDispatcherInstance(); + } else { + // Setup thread dispatcher, and send to proper thread + LogPedantic("Sending event to thread dispatcher"); + m_threadEventDispatcher.SetThread(iterator->second); + dispatcher = &m_threadEventDispatcher; + } + + // Dispatch event to abstract dispatcher + WaitableEvent *synchronization; + + // TODO: Pool synchronization objects + switch (mode) { + case EmitMode::Auto: + // Check thread + if (iterator->second == Thread::GetCurrentThread()) { + // Guard listener code for exceptions + GuardedEventCall(event, iterator->first); + } else { + // Handle non-synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, iterator->first, + DelegateType(), NULL)); + } + break; + + case EmitMode::Queued: + // Handle non-synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, iterator->first, + DelegateType(), NULL)); + + break; + + case EmitMode::Blocking: + // Check thread + if (iterator->second == Thread::GetCurrentThread()) { + // Guard listener code for exceptions + GuardedEventCall(event, iterator->first); + } else { + // New synchronization object is needed + synchronization = new WaitableEvent(); + + // Handle synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, iterator->first, + DelegateType(), synchronization)); + + // Add to barrier + synchronizationBarrier.push_back(synchronization); + } + break; + + case EmitMode::Deffered: + // Handle deffered events + Assert(dueTime >= 0.0 && "Due time must be non-negative"); + + dispatcher->AddTimedEventCall( + RegisterEventCall(event, iterator->first, + DelegateType(), NULL), dueTime); + + break; + + default: + Assert("Invalid emit mode"); + } + } + + LogPedantic("Added event to dispatchers"); + + // Emit to all delegates + FOREACH(iterator, m_delegateList) + { + // Switch to proper dispatcher and emit event + AbstractEventDispatcher *dispatcher = NULL; + + if (iterator->second == NULL) { + // Send to main thread + LogPedantic("Sending event to main dispatcher"); + dispatcher = &GetMainEventDispatcherInstance(); + } else { + // Setup thread dispatcher, and send to proper thread + LogPedantic("Sending event to thread dispatcher"); + m_threadEventDispatcher.SetThread(iterator->second); + dispatcher = &m_threadEventDispatcher; + } + + // Dispatch event to abstract dispatcher + WaitableEvent *synchronization; + + // TODO: Pool synchronization objects + switch (mode) { + case EmitMode::Auto: + // Check thread + if (iterator->second == Thread::GetCurrentThread()) { + // Guard listener code for exceptions + GuardedEventCall(event, iterator->first); + } else { + // Handle non-synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, + NULL, + iterator->first, + NULL)); + } + break; + + case EmitMode::Queued: + // Handle non-synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, + NULL, + iterator->first, + NULL)); + + break; + + case EmitMode::Blocking: + // Check thread + if (iterator->second == Thread::GetCurrentThread()) { + // Guard listener code for exceptions + GuardedEventCall(event, iterator->first); + } else { + // New synchronization object is needed + synchronization = new WaitableEvent(); + + // Handle synchronized event + dispatcher->AddEventCall( + RegisterEventCall(event, + NULL, + iterator->first, + synchronization)); + + // Add to barrier + synchronizationBarrier.push_back(synchronization); + } + break; + + case EmitMode::Deffered: + // Handle deffered events + Assert(dueTime >= 0.0 && "Due time must be non-negative"); + + dispatcher->AddTimedEventCall( + RegisterEventCall(event, + NULL, + iterator->first, + NULL), dueTime); + + break; + + default: + Assert("Invalid emit mode"); + } + } + + LogPedantic("Added event to dispatchers"); + + // Leave listeners lock in case of blocking call + if (!synchronizationBarrier.empty()) { + LogPedantic("Leaving lock due to existing barrier"); + lock.reset(); + } + + LogPedantic("Size of barrier: " << synchronizationBarrier.size()); + + // Synchronize with barrier + // TODO: Implement generic WaitForAllMultipleHandles call + while (!synchronizationBarrier.empty()) { + // Get barrier waitable handles + WaitableHandleList barrierHandles; + + FOREACH(iterator, synchronizationBarrier) + barrierHandles.push_back((*iterator)->GetHandle()); + + // Await more events + WaitableHandleIndexList indexList = + WaitForMultipleHandles(barrierHandles); + + // Remove all awaited handles + // TODO: Return handles to pool + FOREACH(iterator, indexList) + { + // Delete object + delete synchronizationBarrier[*iterator]; + + // Zero out place + synchronizationBarrier[*iterator] = NULL; + } + + // Now clean up + std::vector clearedSynchronizationBarrier; + + FOREACH(iterator, synchronizationBarrier) + { + if (*iterator == NULL) { + continue; + } + + clearedSynchronizationBarrier.push_back(*iterator); + } + + synchronizationBarrier.swap(clearedSynchronizationBarrier); + + LogPedantic("Reduced size of barrier: " + << synchronizationBarrier.size()); + } + + LogPedantic("Event emitted"); + } + + public: + EventSupport() : + m_guardedCallInProgress(false) + {} + + virtual ~EventSupport() + { + if( m_guardedCallInProgress != 0 ){ + LogError("The object will terminate, but guardCall is in progress, it could cause segmentation fault"); + } + + m_eventListenerList.clear(); + m_delegateList.clear(); + + Mutex::ScopedLock lock(&m_eventListMutex); + + LogPedantic("Disabling events for EventSupport"); + + FOREACH(iterator, m_eventsList) + (*iterator)->DisableEvent(); + } + + void AddListener(EventListenerType *eventListener) + { + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + // Listener must not be NULL + Assert(eventListener != NULL); + + // Listener must not already exists + Assert(m_eventListenerList.find(eventListener) + == m_eventListenerList.end()); + + // Add new listener, inherit dispatcher from current context + m_eventListenerList.insert( + std::make_pair(eventListener, Thread::GetCurrentThread())); + + // Done + LogPedantic("Listener registered"); + } + + void AddListener(DelegateType delegate) + { + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + // Delegate must not be empty + Assert(delegate); + + // Delegate must not already exists + Assert(m_delegateList.find(delegate) == m_delegateList.end()); + + // Add new delegate, inherit dispatcher from current context + m_delegateList.insert( + std::make_pair(delegate, Thread::GetCurrentThread())); + + // Done + LogPedantic("Delegate registered"); + } + + void RemoveListener(EventListenerType *eventListener) + { + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + // Listener must not be NULL + Assert(eventListener != NULL); + + // Listener must exist + typename EventListenerList::iterator iterator = + m_eventListenerList.find(eventListener); + + Assert(iterator != m_eventListenerList.end()); + + // Remove listener from list + m_eventListenerList.erase(iterator); + LogPedantic("Listener unregistered"); + } + + void RemoveListener(DelegateType delegate) + { + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + // Delegate must not be empty + Assert(delegate); + + // Delegate must exist + typename DelegateList::iterator iterator = + m_delegateList.find(delegate); + + Assert(iterator != m_delegateList.end()); + + // Remove delegate from list + m_delegateList.erase(iterator); + LogPedantic("Delegate unregistered"); + } + + void SwitchListenerToThread(EventListenerType *eventListener, + Thread *thread) + { + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + // Listener must not be NULL + Assert(eventListener != NULL); + + // Listener must exist + typename EventListenerList::iterator iterator = + m_eventListenerList.find(eventListener); + + Assert(iterator != m_eventListenerList.end()); + + // Set listener thread + iterator->second = thread; + + LogPedantic("Listener switched"); + } + + void SwitchListenerToThread(DelegateType delegate, + Thread *thread) + { + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + // Delegate must not be empty + Assert(!delegate.empty()); + + // Delegate must exist + typename EventListenerList::iterator iterator = + m_delegateList.find(delegate); + + Assert(iterator != m_delegateList.end()); + + // Set delegate thread + iterator->second = thread; + + LogPedantic("Delegate switched"); + } + + void SwitchAllListenersToThread(Thread *thread) + { + Mutex::ScopedLock lock(&m_listenerDelegateMutex); + + // Switch all listeners and delegates + FOREACH(iterator, m_eventListenerList) + iterator->second = thread; + + FOREACH(iterator, m_delegateList) + iterator->second = thread; + + LogPedantic("All listeners and delegates switched"); + } +}; +} +} // namespace DPL + +#endif // DPL_EVENT_SUPPORT_H diff --git a/modules/event/include/dpl/event/generic_event_call.h b/modules/event/include/dpl/event/generic_event_call.h new file mode 100644 index 0000000..2cdf026 --- /dev/null +++ b/modules/event/include/dpl/event/generic_event_call.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_event_call.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of generic event call + */ +#ifndef DPL_GENERIC_EVENT_CALL_H +#define DPL_GENERIC_EVENT_CALL_H + +#include + +#include +#include +#include +#include +#include + +namespace DPL { +namespace Event { +template +class GenericEventCall : + public AbstractEventCall +{ + public: + typedef EventListener EventListenerType; + typedef std::function DelegateType; + + protected: + SupportDataType m_supportData; + EventListenerType *m_eventListener; + DelegateType m_delegate; + EventType m_event; + + public: + template + struct Rebind + { + typedef GenericEventCall Other; + }; + + GenericEventCall(SupportDataType supportData, + EventListenerType *eventListener, + DelegateType delegate, + const EventType &event) : + m_supportData(supportData), + m_eventListener(eventListener), + m_delegate(delegate), + m_event(event) + {} + + virtual ~GenericEventCall() + { + Assert(m_supportData == NULL && + "Call method hasn't been called" + " (support data wasn't destroyed)"); + } + + virtual void Call() + { + LogPedantic("Calling generic event call"); + + m_supportData->CallAndDestroy(m_event, m_eventListener, m_delegate); + + // Now m_supportData points to invalid object. Marking it as NULL. + m_supportData = NULL; + + LogPedantic("Generic event called"); + } + + virtual void DisableEvent() + { + LogPedantic("Disabling this EventCall"); + m_supportData->Reset(); + + // TODO: In the future, event should be completely removed + // from the event queue (not just marked "disabled") + } +}; +} +} // namespace DPL + +#endif // DPL_GENERIC_EVENT_CALL_H diff --git a/modules/event/include/dpl/event/inter_context_delegate.h b/modules/event/include/dpl/event/inter_context_delegate.h new file mode 100644 index 0000000..2d711fe --- /dev/null +++ b/modules/event/include/dpl/event/inter_context_delegate.h @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file inter_context_delegate.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the header file of inter context delegate + */ + +#ifndef DPL_INTER_CONTEXT_DELEGATE_H_ +#define DPL_INTER_CONTEXT_DELEGATE_H_ + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ // C++11 compatibility check +# include +#else + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * - Created ICDelegate can be passed freely to other threads. + * - ICDelegate can be called just once. All following calls will be + * silently ignored. + * - When ICDelegateSupport is destroyed, all its ICDelegates + * are invalidated and safetly removed. + * - ICDelegate can be invalidated by call to disable method on it. + * - To use ICDelegate you have to do two steps: + * + * 1. Class that will be used to create delegate have to derive from templated + * class ICDelegateSupport + * + * 2. Create instance of ICDelegate by calling + * makeICDelegate and passing to it pointer to method + * + * class A : ICDelegateSupport + * { + * void methodA(int) {} + * void createDelegate() { + * ICDelegate dlg; + * dlg = makeICDelegate(&A::MethodA); + * }; + */ + +namespace DPL { +namespace Event { +//forward declaration +template +class ICDelegate; + +namespace ICD { +// This Type defines whether ICDelegate should be destroyed after the call, or +// could be reused later. +enum class Reuse +{ + Yes, No +}; +} + +namespace ICDPrivate { +// Base for all ICDSharedDatas. Needed for auto disabling and deleting of +// ICDSharedDatas. +// If ICDSharedData is disabled, delegate won't be called anymore. +class ICDSharedDataBase +{ + public: + typedef std::shared_ptr ICDSharedDataBasePtr; + typedef std::list ICDSharedDataBaseList; + + class ScopedLock : DPL::Noncopyable + { + public: + explicit ScopedLock(ICDSharedDataBasePtr helperBase) : + m_scopedLock(&helperBase->m_mutex) + {} + + private: + DPL::RecursiveMutex::ScopedLock m_scopedLock; + }; + + ICDSharedDataBase() : m_disabled(false) + {} + virtual ~ICDSharedDataBase() + {} + + bool isDisabled() const + { + return m_disabled; + } + virtual void disable() + { + m_disabled = true; + } + + void setIterator(ICDSharedDataBaseList::iterator pos) + { + m_position = pos; + } + + ICDSharedDataBaseList::iterator getIterator() const + { + return m_position; + } + + private: + bool m_disabled; + DPL::RecursiveMutex m_mutex; + ICDSharedDataBaseList::iterator m_position; +}; + +// Pure Event to remove ICDSharedData. +class DeleteICDSharedDataBaseEventCall : public DPL::Event::AbstractEventCall +{ + public: + DeleteICDSharedDataBaseEventCall( + ICDSharedDataBase::ICDSharedDataBasePtr helperBase) : + m_helperBase(helperBase) + {} + virtual void Call() + { + m_helperBase.reset(); + } + + private: + ICDSharedDataBase::ICDSharedDataBasePtr m_helperBase; +}; + +class ICDelegateSupportInterface +{ + protected: + virtual ~ICDelegateSupportInterface() + {} + virtual void unregisterICDSharedData( + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr helper) = 0; + virtual void registerICDSharedData( + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr helper) = 0; + + private: + template + friend class DPL::Event::ICDelegate; +}; +} //ICDPrivate + +template +std::function +makeDelegate(ThisType* This, + void (ThisType::*Func)(ArgTypesList ...)) +{ + return DPL::Bind(Func, This); +} + +// ICDelegate class represents delegate that can be called from +// any context (thread). The actual calling context (thread) is allways the same +// as the context in which it was created. +template +class ICDelegate +{ + public: + ICDelegate() + {} + ICDelegate(ICDPrivate::ICDelegateSupportInterface* base, + std::function outerDelegate, + ICD::Reuse reuse) + { + ICDSharedData* hlp = new ICDSharedData(base, outerDelegate, reuse); + m_helper.reset(hlp); + } + + // Calling operator will pass all args passed to it to correct context and + // will call apropriate method that was registered with. + void operator()(ArgTypesList ... args) + { + Assert(m_helper); + ICDPrivate::ICDSharedDataBase::ScopedLock lock( + std::static_pointer_cast(m_helper)); + m_helper->CallDelegate(args ...); + } + + //Disable delegate (it won't be called anymore) + void disable() + { + Assert(m_helper); + ICDPrivate::ICDSharedDataBase::ScopedLock lock( + std::static_pointer_cast(m_helper)); + m_helper->disable(); + } + + protected: + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr + getRelatedICDSharedData() const + { + return std::static_pointer_cast(m_helper); + } + + private: + template + friend class ICDelegateSupport; + class ICDSharedData; + typedef std::shared_ptr ICDSharedDataPtr; + + struct PrivateEvent + { + PrivateEvent(ICDSharedDataPtr a_helper, + ArgTypesList ... arguments) : + helper(a_helper), + args(std::make_tuple(arguments ...)) + {} + + ICDSharedDataPtr helper; + std::tuple args; + }; + + typedef std::function + ICDSharedDataDelegateType; + class ICDSharedData : private DPL::Event::EventSupport, + public std::enable_shared_from_this, + public ICDPrivate::ICDSharedDataBase + { + public: + ICDSharedData( + ICDPrivate::ICDelegateSupportInterface *base, + std::function outerDelegate, + ICD::Reuse reuse) : + m_base(base), + m_outerDelegate(outerDelegate), + m_reuse(reuse) + { + Assert(m_base); + // lock is not needed: this object is not shared at that moment + m_subDelegate = + DPL::Event::makeDelegate(this, + &ICDSharedData::delegateForwarder); + EventSupport::AddListener(m_subDelegate); + } + + void CallDelegate(ArgTypesList ... args) + { + ICDPrivate::ICDSharedDataBase::ScopedLock lock( + std::static_pointer_cast( + this->shared_from_this())); + if (!isDisabled()) { + EmitEvent(PrivateEvent(this->shared_from_this(), + args ...)); + } + } + + virtual void disable() + { + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr ptr( + std::static_pointer_cast( + this->shared_from_this())); + ICDPrivate::ICDSharedDataBase::ScopedLock lock(ptr); + if (!isDisabled()) { + ICDPrivate::ICDSharedDataBase::disable(); + EventSupport::RemoveListener(m_subDelegate); + m_base->unregisterICDSharedData(ptr); + } + } + + private: + friend class std::shared_ptr; + ICDSharedDataDelegateType m_subDelegate; + ICDPrivate::ICDelegateSupportInterface* m_base; + std::function m_outerDelegate; + ICD::Reuse m_reuse; + + void delegateForwarder(const PrivateEvent& event) + { + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr ptr( + std::static_pointer_cast(event.helper)); + ICDPrivate::ICDSharedDataBase::ScopedLock lock(ptr); + + Assert(m_outerDelegate); + if (ptr->isDisabled()) { + LogPedantic("ICDSharedData has been disabled - call is ignored"); + } else { + DPL::Apply(m_outerDelegate, event.args); + + if (m_reuse == ICD::Reuse::Yes) { + return; + } + + disable(); + deleteICDSharedDataBase(ptr); + } + } + }; + + // Schedules helper removal. + static void deleteICDSharedDataBase( + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr helper) + { + using namespace ICDPrivate; + ICDSharedDataBase::ScopedLock lock(helper); + DeleteICDSharedDataBaseEventCall* event = + new DeleteICDSharedDataBaseEventCall(helper); + if (DPL::Thread::GetCurrentThread() == NULL) { + DPL::Event::GetMainEventDispatcherInstance().AddEventCall(event); + } else { + DPL::Event::ThreadEventDispatcher dispatcher; + dispatcher.SetThread(DPL::Thread::GetCurrentThread()); + dispatcher.AddEventCall(event); + } + } + + ICDSharedDataPtr m_helper; +}; + +template +class ICDelegateSupport : public ICDPrivate::ICDelegateSupportInterface +{ + protected: + template + ICDelegate makeICDelegate( + void (ThisType::*Func)(ArgTypesList ...), + ICD::Reuse reuse = ICD::Reuse::No) + { + ThisType* This = static_cast(this); + ICDelegate icdelegate( + This, + makeDelegate(This, Func), + reuse); + this->registerICDSharedData(icdelegate.getRelatedICDSharedData()); + return icdelegate; + } + + ICDelegateSupport() + {} + + ~ICDelegateSupport() + { + ICDPrivate::ICDSharedDataBase::ICDSharedDataBaseList list = + m_ICDSharedDatas; + FOREACH(helper, list) { + ICDPrivate::ICDSharedDataBase::ScopedLock lock( + std::static_pointer_cast(*helper)); + (*helper)->disable(); + } + m_ICDSharedDatas.clear(); + } + + private: + virtual void unregisterICDSharedData( + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr helper) + { + m_ICDSharedDatas.erase(helper->getIterator()); + } + + virtual void registerICDSharedData( + ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr helper) + { + helper->setIterator( + m_ICDSharedDatas.insert(m_ICDSharedDatas.begin(), + helper)); + } + + private: + ICDPrivate::ICDSharedDataBase::ICDSharedDataBaseList m_ICDSharedDatas; +}; +} +} //namespace + +#endif // __GXX_EXPERIMENTAL_CXX0X__ + +#endif //DPL_INTER_CONTEXT_DELEGATE_H_ diff --git a/modules/event/include/dpl/event/main_event_dispatcher.h b/modules/event/include/dpl/event/main_event_dispatcher.h new file mode 100644 index 0000000..db86b1f --- /dev/null +++ b/modules/event/include/dpl/event/main_event_dispatcher.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main_event_dispatcher.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main event dispatcher + * for EFL + */ +#ifndef DPL_MAIN_EVENT_DISPATCHER_H +#define DPL_MAIN_EVENT_DISPATCHER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Event { +class MainEventDispatcher : + public AbstractEventDispatcher +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + DECLARE_EXCEPTION_TYPE(Base, AddEventFailed) + DECLARE_EXCEPTION_TYPE(Base, AddTimedEventFailed) + }; + + protected: + struct WrappedEventCall + { + AbstractEventCall *abstractEventCall; + bool timed; + double dueTime; + + WrappedEventCall(AbstractEventCall *abstractEventCallArg, + bool timedArg, + double dueTimeArg) : + abstractEventCall(abstractEventCallArg), + timed(timedArg), + dueTime(dueTimeArg) + {} + }; + + typedef std::list WrappedEventCallList; + + // Cross thread send support + WrappedEventCallList m_wrappedCrossEventCallList; + Mutex m_crossEventCallMutex; + WaitableEvent* m_crossEventCallInvoker; + + Ecore_Event_Handler *m_eventCallHandler; + Ecore_Fd_Handler *m_crossEventCallHandler; + + int m_eventId; + + // Timed event support + struct TimedEventStruct + { + AbstractEventCall *abstractEventCall; + MainEventDispatcher *This; + + TimedEventStruct(AbstractEventCall *abstractEventCallArg, + MainEventDispatcher *ThisArg) : + abstractEventCall(abstractEventCallArg), + This(ThisArg) + {} + }; + + void InternalAddEvent(AbstractEventCall *abstractEventCall, + bool timed, + double dueTime); + + static void StaticDeleteEvent(void *data, void *event); + static Eina_Bool StaticDispatchEvent(void *data, int type, void *event); + static Eina_Bool StaticDispatchTimedEvent(void *event); + static Eina_Bool StaticDispatchCrossInvoker(void *data, + Ecore_Fd_Handler *fd_handler); + + void DeleteEvent(AbstractEventCall *abstractEventCall); + void DispatchEvent(AbstractEventCall *abstractEventCall); + void DispatchTimedEvent(AbstractEventCall *abstractEventCall); + void DispatchCrossInvoker(); + + public: + explicit MainEventDispatcher(); + virtual ~MainEventDispatcher(); + + virtual void AddEventCall(AbstractEventCall *abstractEventCall); + virtual void AddTimedEventCall(AbstractEventCall *abstractEventCall, + double dueTime); + virtual void ResetCrossEventCallHandler(); +}; + +MainEventDispatcher& GetMainEventDispatcherInstance(); +} +} // namespace DPL + +#endif // DPL_MAIN_EVENT_DISPATCHER_H diff --git a/modules/event/include/dpl/event/model.h b/modules/event/include/dpl/event/model.h new file mode 100644 index 0000000..b149eee --- /dev/null +++ b/modules/event/include/dpl/event/model.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file model.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for model + */ +#ifndef DPL_MODEL_H +#define DPL_MODEL_H + +#include +#include + +namespace DPL { +namespace Event { +class Model : + public Noncopyable +{ + protected: + mutable DPL::ReadWriteMutex m_mutex; + + template + friend class PropertyBase; + + template + friend class Property; + + public: + virtual ~Model() = 0; +}; +} +} // namespace DPL + +#endif // DPL_MODEL_H diff --git a/modules/event/include/dpl/event/model_bind_to_dao.h b/modules/event/include/dpl/event/model_bind_to_dao.h new file mode 100644 index 0000000..2ed7e0e --- /dev/null +++ b/modules/event/include/dpl/event/model_bind_to_dao.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file model_bind_to_dao.h + * @author Grzegorz Krawczyk (g.krawczyk@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef DPL_MODEL_BIND_TO_DAO_H_ +#define DPL_MODEL_BIND_TO_DAO_H_ + +namespace DPL { +namespace Event { +/** + * @param ObjectType type of object used as delegate argument + * @param RetType Type returned from the external function + * @param ExtArg Type of argument required by external fun + * @param getterFun Object Type method which returns value of type ExtArg + * used as argument for external function + * */ +//STATIC FUNCTION +template < + typename ObjectType, + typename ValueType, + typename ExtArg, + ExtArg(ObjectType::*argGetter) () const, + ValueType(*externalGetter) (ExtArg) + > +struct BindToDAO_Static +{ + static ValueType Get(DPL::Event::Model* obj) + { + ObjectType* instance = static_cast(obj); + + return externalGetter((instance->*argGetter)()); + } +}; + +template < + typename ObjectType, + typename ValueType, + typename ExtArg, + typename ExtObject, + ExtArg(ObjectType::*argGetter) () const, + ValueType(ExtObject::*externalGetter) () const + > +struct BindToDAO +{ + static ValueType Get(DPL::Event::Model* obj) + { + ObjectType* instance = static_cast(obj); + ExtObject extObject((instance->*argGetter)()); + return (extObject.*externalGetter)(); + } +}; +} +} + +#endif diff --git a/modules/event/include/dpl/event/property.h b/modules/event/include/dpl/event/property.h new file mode 100644 index 0000000..ce2e5c7 --- /dev/null +++ b/modules/event/include/dpl/event/property.h @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file property.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for property + */ +#ifndef DPL_PROPERTY_H +#define DPL_PROPERTY_H + +#include + +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Event { +/** + * Property is a class that encapsulates model's property fields. + * Its main purpose is to automate things related to model's properties + * such as: data storage, synchronization and event emitting. + * + * Property is a template of the following schema: + * + * template class Property + * + * Type is an internal type that property is encapsulating. It is required + * that the type is default-constructible and copyable. + * + * Property access rights control which operations are allowed to be + * executed on property. + * + * Property storage mode is a mode describing where and how internal data should + * be stored. + * + * Property modifiers: + * + * PropertyStorageCached: The data is stored internally as one copy. It can + * never be changed from external. + * + * PropertyStorageDynamic: The data is stored remotely and is accessed via + * provided delegates. It can change at any time + * if external mechanism changes its value. + * + * PropertyStorageDynamicCached: The data is stored internally, but only after + * it has been retrieved by delegates. The + * changed data is stored internally and also set + * remotely with delegate. After the value has + * been received from external source, it will + * never be updated externally. + * + * Property access modes: + * + * PropertyReadOnly: Property is a read-only property. + * It doesn't have Set() method. + * + * PropertyReadWrite: Property is a read-write property. It have both Get() + * and Set() methods. + * + * Examples: + * + * Note: All properties, if not specified otherwise in template arguments, + * have read-write access rights and cached data storage. + * + * Simple property with int: + * @code DPL::Property Number; + * + * A property with string: + * @code DPL::Property Name; + * + * A read-only float property: + * @code DPL::Property Gravity; + * + * A read-write string property: + * @code DPL::Property Caption; + * + * A read-write string property which is stored internally: + * @code DPL::Property Name; + * + * A read-write string property which is stored externally: + * @code DPL::Property RemoteName; + * + * A read-write string property which is stored externally, but also cached: + * @code DPL::Property CachedName; + * + * A model is an agregation of many properties. Whenever some of them change, + * an event with this change is emmited along with model handle which + * contains this property. These changes can be listened to. To achieve this, + * one have to add a delegate which contains changed property value and + * a pointer to the model. + * + * Example of a model with a property: + * + * @code + * class MyModel: public DPL::Model + * { + * public: + * DPL::Property Number1; + * DPL::Property Number2; + * DPL::Property Number3; + * + * // Read write property delegate method can be static + * static int ReadCustomValue(Model *model); + * + * // Read write property delegate method can also be method + * void WriteCustomValue(const int &value, Model *model); + * + * MyModel() + * : // Initialize property with default value and this model + * Number1(this), + * + * // Initialize property with 123 and this model + * Number2(this, 123), + * + * // Initialize property with 0 and custom read delegate and this model + * Number3(this, 0, &ReadCustomValue), + * + * // Initialize property with 7 and custom read-write delegates + * // and this model + * Number4(this, 7, &ReadCustomValue, + * std::bind(&WriteCustomValue, this) + * { + * } + * }; + * + * DPL's delegate mechanism is a general solution, which is capable of + * binding various types of functions and method as a delegate and + * using them in unified way. + * + * Example of registering and unregistering for model's property changes: + * + * @code + * class SomeModel : public DPL::Model + * { + * public: + * DPL::Property Value; + * + * SomeModel() + * : Value(this) + * { + * } + * }; + * + * void ValueChanged(const int &value, Model *model) + * { + * std::cout << "Value changed to: " << value << std::endl; + * } + * + * int main() + * { + * SomeModel model; + * + * // Register a global function as property changed listener + * model.AddListener(&ValueChanged); + * [...] + * model.RemoveListener(&ValueChanged); + * + * // Register a class method as property changed listener + * class Receiver + * { + * public: + * void OnValueChanged(const int &value, Model *model) + * { + * [...] + * } + * } receiver; + * + * model.AddListener( + * std::bind(&Receiver::OnValueChanged, &receiver)); + * [...] + * model.RemoveListener( + * std::bind(&Receiver::OnValueChanged, &receiver)); + * } + */ +struct PropertyStorageCached {}; ///< Always use cached +struct PropertyStorageDynamic {}; ///< Always use dynamic +struct PropertyStorageDynamicCached {}; ///< Use dynamic then cache + +struct PropertyReadOnly {}; ///< Read only, not setter available +struct PropertyReadWrite {}; ///< Read and write + +template +struct PropertyEvent +{ + PropertyEvent(const Type &v, Model *s) : + value(v), + sender(s) + {} + + Type value; + Model *sender; +}; + +template +class PropertyStorageMethodDynamicBase +{ + protected: + ReadDelegateType m_readValue; + WriteDelegateType m_writeValue; + + PropertyStorageMethodDynamicBase(ReadDelegateType readValue, + WriteDelegateType writeValue) : + m_readValue(readValue), + m_writeValue(writeValue) + {} +}; + +template +class PropertyStorageMethodCachedBase +{ + protected: + mutable Type m_value; + + PropertyStorageMethodCachedBase() + {} +}; + +class PropertyStorageMethodBase +{ + protected: + explicit PropertyStorageMethodBase(Model *model) : + m_model(model) + {} + + Model *m_model; +}; + +template +class PropertyStorageMethod; + +template +class PropertyStorageMethod: + protected PropertyStorageMethodBase, + protected PropertyStorageMethodCachedBase +{ + public: + PropertyStorageMethod(Model *model, + ReadDelegateType /*readValue*/, + WriteDelegateType /*writeValue*/) : + PropertyStorageMethodBase(model) + {} + + Type Get() const + { + return this->m_value; + } + + void Set(const Type &value) + { + this->m_value = value; + } +}; + +template +class PropertyStorageMethod: + protected PropertyStorageMethodBase, + protected PropertyStorageMethodDynamicBase +{ + public: + PropertyStorageMethod(Model *model, + ReadDelegateType readValue, + WriteDelegateType writeValue) : + PropertyStorageMethodBase(model), + PropertyStorageMethodDynamicBase( + readValue, + writeValue) + {} + + Type Get() const + { + Assert(this->m_readValue); + return this->m_readValue(m_model); + } + + void Set(const Type &value) + { + Assert(this->m_writeValue); + this->m_writeValue(value, m_model); + } +}; + +template +class PropertyStorageMethod: + protected PropertyStorageMethodBase, + protected PropertyStorageMethodDynamicBase, + protected PropertyStorageMethodCachedBase +{ + private: + typedef PropertyStorageMethod ThisType; + + // These two are mutable + void OnceEnsure() const + { + this->m_value = this->m_readValue(m_model); + } + + void OnceDisable() const + {} + + protected: + mutable Once m_once; + + public: + PropertyStorageMethod(Model *model, + ReadDelegateType readValue, + WriteDelegateType writeValue) : + PropertyStorageMethodBase(model), + PropertyStorageMethodDynamicBase( + readValue, writeValue) + {} + + Type Get() const + { + Assert(this->m_readValue); + m_once.Call(std::bind(&ThisType::OnceEnsure, this)); + return this->m_value; + } + + void Set(const Type &value) + { + Assert(this->m_writeValue); + + this->m_writeValue(value, m_model); + this->m_value = value; + m_once.Call(std::bind(&ThisType::OnceDisable, this)); + } +}; + +template +class PropertyBase : + protected EventSupport > +{ + public: + typedef typename EventSupport >::EventListenerType + EventListenerType; + + typedef typename EventSupport >::DelegateType + DelegateType; + + typedef std::function + ReadDelegateType; + + typedef std::function + WriteDelegateType; + + protected: + PropertyStorageMethod m_storage; + Model *m_model; + + PropertyBase(Model *model, + ReadDelegateType readValue, + WriteDelegateType writeValue) : + m_storage(model, readValue, writeValue), + m_model(model) + {} + + public: + virtual Type Get() const + { + ReadWriteMutex::ScopedReadLock lock(&m_model->m_mutex); + return m_storage.Get(); + } + + void AddListener(DelegateType delegate) + { + EventSupport >::AddListener(delegate); + } + + void RemoveListener(DelegateType delegate) + { + EventSupport >::RemoveListener(delegate); + } +}; + +template +class Property; + +template +class Property: + public PropertyBase +{ + public: + typedef typename PropertyBase::EventListenerType + EventListenerType; + + typedef typename PropertyBase::DelegateType + DelegateType; + + typedef typename PropertyBase::ReadDelegateType + ReadDelegateType; + + typedef typename PropertyBase::WriteDelegateType + WriteDelegateType; + + public: + explicit Property(Model *model, + ReadDelegateType readValue = NULL) : + PropertyBase(model, readValue, NULL) + {} + + Property(Model *model, + const Type &value, + ReadDelegateType readValue = NULL) : + PropertyBase(model, readValue, NULL) + { + this->m_storage.Set(value); + } +}; + +template +class Property: + public PropertyBase +{ + public: + typedef typename PropertyBase::EventListenerType + EventListenerType; + + typedef typename PropertyBase::DelegateType + DelegateType; + + typedef typename PropertyBase::ReadDelegateType + ReadDelegateType; + + typedef typename PropertyBase::WriteDelegateType + WriteDelegateType; + + public: + explicit Property(Model *model, + ReadDelegateType readValue = NULL, + WriteDelegateType writeValue = NULL) : + PropertyBase(model, readValue, writeValue) + {} + + Property(Model *model, + const Type &value, + ReadDelegateType readValue = NULL, + WriteDelegateType writeValue = NULL) : + PropertyBase(model, readValue, writeValue) + { + this->m_storage.Set(value); + } + + virtual void Set(const Type &value) + { + ReadWriteMutex::ScopedWriteLock lock(&this->m_model->m_mutex); + + if (this->m_storage.Get() == value) { + return; + } + + this->m_storage.Set(value); + + this->EmitEvent(PropertyEvent(value, this->m_model), + EmitMode::Auto); + } + + void SetWithoutLock(const Type &value) + { + if (this->m_storage.Get() == value) { + return; + } + + this->m_storage.Set(value); + } +}; +} +} // namespace DPL + +#endif // DPL_PROPERTY_H diff --git a/modules/event/include/dpl/event/thread_event_dispatcher.h b/modules/event/include/dpl/event/thread_event_dispatcher.h new file mode 100644 index 0000000..f3846a6 --- /dev/null +++ b/modules/event/include/dpl/event/thread_event_dispatcher.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread_event_dispatcher.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of thread event dispatcher + */ +#ifndef DPL_THREAD_EVENT_DISPATCHER_H +#define DPL_THREAD_EVENT_DISPATCHER_H + +#include +#include +#include + +namespace DPL { +namespace Event { +class ThreadEventDispatcher : + public AbstractEventDispatcher +{ + protected: + Thread *m_thread; + + static void StaticEventDelete(void *event, void *userParam); + static void StaticEventDispatch(void *event, void *userParam); + + void EventDelete(AbstractEventCall *abstractEventCall); + void EventDispatch(AbstractEventCall *abstractEventCall); + + public: + explicit ThreadEventDispatcher(); + virtual ~ThreadEventDispatcher(); + + void SetThread(Thread *thread); + + virtual void AddEventCall(AbstractEventCall *abstractEventCall); + virtual void AddTimedEventCall(AbstractEventCall *abstractEventCall, + double dueTime); +}; +} +} // namespace DPL + +#endif // DPL_THREAD_EVENT_DISPATCHER_H diff --git a/modules/event/src/abstract_event_call.cpp b/modules/event/src/abstract_event_call.cpp new file mode 100644 index 0000000..748b6da --- /dev/null +++ b/modules/event/src/abstract_event_call.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_event_call.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract event call + */ +#include +#include + +namespace DPL { +namespace Event { +AbstractEventCall::AbstractEventCall() +{} + +AbstractEventCall::~AbstractEventCall() +{} +} +} // namespace DPL diff --git a/modules/event/src/abstract_event_dispatcher.cpp b/modules/event/src/abstract_event_dispatcher.cpp new file mode 100644 index 0000000..7c385a4 --- /dev/null +++ b/modules/event/src/abstract_event_dispatcher.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_event_dispatcher.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract event + * dispatcher + */ +#include +#include + +namespace DPL { +namespace Event { +AbstractEventDispatcher::AbstractEventDispatcher() +{} + +AbstractEventDispatcher::~AbstractEventDispatcher() +{} +} +} // namespace DPL diff --git a/modules/event/src/controller.cpp b/modules/event/src/controller.cpp new file mode 100644 index 0000000..337a39f --- /dev/null +++ b/modules/event/src/controller.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file controller.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC controller + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/event/src/event_listener.cpp b/modules/event/src/event_listener.cpp new file mode 100644 index 0000000..5d0d382 --- /dev/null +++ b/modules/event/src/event_listener.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file event_listener.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC event listener + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/event/src/event_support.cpp b/modules/event/src/event_support.cpp new file mode 100644 index 0000000..d2e643c --- /dev/null +++ b/modules/event/src/event_support.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file event_support.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of MVC event support + */ +#include +#include + +namespace DPL { +namespace Event { +namespace // anonymous +{ +int dummyInitializerProc() +{ + GetMainEventDispatcherInstance(); + return 0; +} + +int g_dummyInitializer = dummyInitializerProc(); +} // namespace anonymous +} +} // namespace DPL + diff --git a/modules/event/src/generic_event_call.cpp b/modules/event/src/generic_event_call.cpp new file mode 100644 index 0000000..d0d6886 --- /dev/null +++ b/modules/event/src/generic_event_call.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_event_call.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of generic event call + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/event/src/inter_context_delegate.cpp b/modules/event/src/inter_context_delegate.cpp new file mode 100644 index 0000000..07e3885 --- /dev/null +++ b/modules/event/src/inter_context_delegate.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file inter_context_delegate.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of ICDelegate functionality + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/event/src/main_event_dispatcher.cpp b/modules/event/src/main_event_dispatcher.cpp new file mode 100644 index 0000000..c860398 --- /dev/null +++ b/modules/event/src/main_event_dispatcher.cpp @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main_event_dispatcher.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main event dispatcher + * for EFL + */ +#include +#include +#include +#include +#include + +namespace DPL { +IMPLEMENT_SINGLETON(Event::MainEventDispatcher) + +namespace Event { +typedef Singleton MainEventDispatcherSingleton; + +namespace // anonymous +{ +static const pthread_t g_threadMain = pthread_self(); + +// Late EFL event handling +MainEventDispatcher *g_lateMainEventDispatcher = NULL; +} // namespace anonymous + +MainEventDispatcher::MainEventDispatcher() +{ + // Late EFL event handling + Assert(g_lateMainEventDispatcher == NULL); + g_lateMainEventDispatcher = this; + + // Increment ECORE init count to ensure we have all + // subsystems correctly set-up until main dispatcher dtor + // This is especially important when MainEventDispatcher + // is a global object destroyed no earlier than crt destroy routine + ecore_init(); + + // Add new global ECORE event + m_eventId = ecore_event_type_new(); + + LogPedantic("ECORE event class registered: " << m_eventId); + + // Register event class handler + if ((m_eventCallHandler = + ecore_event_handler_add(m_eventId, &StaticDispatchEvent, + this)) == NULL) + { + ThrowMsg(Exception::CreateFailed, "Failed to register event handler!"); + } + + // Allocate WaitableEvent + m_crossEventCallInvoker = new WaitableEvent(); + + // Register cross event handler + m_crossEventCallHandler = ecore_main_fd_handler_add( + m_crossEventCallInvoker->GetHandle(), + ECORE_FD_READ, + &StaticDispatchCrossInvoker, + this, + NULL, + NULL); + + if (m_crossEventCallHandler == NULL) { + ThrowMsg(Exception::CreateFailed, + "Failed to register cross event handler!"); + } + + LogPedantic("ECORE cross-event handler registered"); +} + +MainEventDispatcher::~MainEventDispatcher() +{ + // Remove cross event handler + ecore_main_fd_handler_del(m_crossEventCallHandler); + m_crossEventCallHandler = NULL; + LogPedantic("ECORE cross-event handler unregistered"); + + // Remove m_crossEventCallInvoker + delete m_crossEventCallInvoker; + m_crossEventCallInvoker = NULL; + + // Remove event class handler + ecore_event_handler_del(m_eventCallHandler); + m_eventCallHandler = NULL; + + // Decrement ECORE init count + // We do not need ecore routines any more + ecore_shutdown(); + + // Late EFL event handling + Assert(g_lateMainEventDispatcher == this); + g_lateMainEventDispatcher = NULL; +} + +void MainEventDispatcher::ResetCrossEventCallHandler() +{ + // Remove cross event handler + ecore_main_fd_handler_del(m_crossEventCallHandler); + m_crossEventCallHandler = NULL; + LogPedantic("ECORE cross-event handler unregistered"); + + // Re-allocate WaitableEvent + delete m_crossEventCallInvoker; + m_crossEventCallInvoker = new WaitableEvent(); + + // Register cross event handler + m_crossEventCallHandler = + ecore_main_fd_handler_add(m_crossEventCallInvoker->GetHandle(), + ECORE_FD_READ, + &StaticDispatchCrossInvoker, + this, + NULL, + NULL); + + if (m_crossEventCallHandler == NULL) { + ThrowMsg(Exception::CreateFailed, + "Failed to register cross event handler!"); + } + + LogPedantic("ECORE cross-event handler re-registered"); +} + +void MainEventDispatcher::StaticDeleteEvent(void *data, void *event) +{ + LogPedantic("Static ECORE delete event handler"); + + MainEventDispatcher *This = static_cast(data); + AbstractEventCall *abstractEventCall = + static_cast(event); + + Assert(This != NULL); + Assert(abstractEventCall != NULL); + + // Late EFL event handling + if (g_lateMainEventDispatcher == NULL) { + LogPedantic("WARNING: Late EFL event delete!"); + delete abstractEventCall; + } else { + This->DeleteEvent(abstractEventCall); + } +} + +Eina_Bool MainEventDispatcher::StaticDispatchEvent(void *data, + int type, + void *event) +{ + LogPedantic("Static ECORE dispatch event"); + + MainEventDispatcher *This = static_cast(data); + AbstractEventCall *abstractEventCall = + static_cast(event); + (void)type; + + Assert(This != NULL); + Assert(abstractEventCall != NULL); + + // Late EFL event handling + if (g_lateMainEventDispatcher == NULL) { + LogPedantic("WARNING: Late EFL event dispatch!"); + } else { + This->DispatchEvent(abstractEventCall); + } + + // Continue to handler other ECORE events + return ECORE_CALLBACK_RENEW; +} + +Eina_Bool MainEventDispatcher::StaticDispatchTimedEvent(void *data) +{ + LogPedantic("Static ECORE dispatch timed event"); + + TimedEventStruct *timedEventStruct = static_cast(data); + MainEventDispatcher *This = timedEventStruct->This; + AbstractEventCall *abstractEventCall = timedEventStruct->abstractEventCall; + delete timedEventStruct; + + Assert(This != NULL); + Assert(abstractEventCall != NULL); + + // Late EFL event handling + if (g_lateMainEventDispatcher == NULL) { + LogPedantic("WARNING: Late EFL timed event dispatch!"); + } else { + // Dispatch timed event + This->DispatchEvent(abstractEventCall); + } + + // And delete manually event, because ECORE does not + // use delete handler for timers + StaticDeleteEvent(static_cast(This), + static_cast(abstractEventCall)); + + // Do not continue timed event handlers + // This also releases ECORE timer + return ECORE_CALLBACK_CANCEL; +} + +Eina_Bool MainEventDispatcher::StaticDispatchCrossInvoker( + void *data, + Ecore_Fd_Handler * + fd_handler) +{ + LogPedantic("Static ECORE dispatch cross invoker"); + + MainEventDispatcher *This = static_cast(data); + (void)fd_handler; + + Assert(This != NULL); + + // Late EFL event handling + if (g_lateMainEventDispatcher == NULL) { + LogPedantic("WARNING: Late EFL cross invoker dispatch!"); + } else { + This->DispatchCrossInvoker(); + } + + return ECORE_CALLBACK_RENEW; +} + +void MainEventDispatcher::DeleteEvent(AbstractEventCall *abstractEventCall) +{ + LogPedantic("ECORE delete event"); + delete abstractEventCall; +} + +void MainEventDispatcher::DispatchEvent(AbstractEventCall *abstractEventCall) +{ + LogPedantic("ECORE dispatch event"); + + // Call event handler + abstractEventCall->Call(); +} + +void MainEventDispatcher::DispatchTimedEvent( + AbstractEventCall *abstractEventCall) +{ + LogPedantic("ECORE dispatch timed event"); + + // Call event handler + abstractEventCall->Call(); +} + +void MainEventDispatcher::DispatchCrossInvoker() +{ + LogPedantic("ECORE dispatch cross invoker"); + + // Steal cross events list + WrappedEventCallList stolenCrossEvents; + + // Critical section + { + m_crossEventCallInvoker->Reset(); + Mutex::ScopedLock lock(&m_crossEventCallMutex); + m_wrappedCrossEventCallList.swap(stolenCrossEvents); + } + + LogPedantic( + "Cross-thread event list stolen. Number of events: " << + stolenCrossEvents.size()); + + // Repush all stolen events + WrappedEventCallList::const_iterator eventIterator; + + for (eventIterator = stolenCrossEvents.begin(); + eventIterator != stolenCrossEvents.end(); + ++eventIterator) + { + // Unwrap events + LogPedantic("Dispatching event from invoker"); + InternalAddEvent(eventIterator->abstractEventCall, + eventIterator->timed, + eventIterator->dueTime); + } + + LogPedantic("Cross-thread events dispatched"); +} + +void MainEventDispatcher::AddEventCall(AbstractEventCall *abstractEventCall) +{ + if (pthread_equal(pthread_self(), g_threadMain)) { + LogPedantic("Main thread ECORE event push"); + InternalAddEvent(abstractEventCall, false, 0.0); + } else { + LogPedantic("Cross-thread ECORE event push"); + + // Push event to cross event list + { + Mutex::ScopedLock lock(&m_crossEventCallMutex); + m_wrappedCrossEventCallList.push_back(WrappedEventCall( + abstractEventCall, false, + 0.0)); + m_crossEventCallInvoker->Signal(); + } + + LogPedantic("Event pushed to cross-thread event list"); + } +} + +void MainEventDispatcher::AddTimedEventCall( + AbstractEventCall *abstractEventCall, + double dueTime) +{ + if (pthread_equal(pthread_self(), g_threadMain)) { + LogPedantic("Main thread timed ECORE event push"); + InternalAddEvent(abstractEventCall, true, dueTime); + } else { + LogPedantic("Cross-thread timed ECORE event push"); + + // Push event to cross event list + { + Mutex::ScopedLock lock(&m_crossEventCallMutex); + m_wrappedCrossEventCallList.push_back(WrappedEventCall( + abstractEventCall, true, + dueTime)); + m_crossEventCallInvoker->Signal(); + } + + LogPedantic("Event pushed to cross-thread event list"); + } +} + +void MainEventDispatcher::InternalAddEvent(AbstractEventCall *abstractEventCall, + bool timed, + double dueTime) +{ + LogPedantic("Adding base event"); + + if (timed == true) { + // Push timed event onto ecore stack + TimedEventStruct* eventData = new TimedEventStruct(abstractEventCall, + this); + Ecore_Timer *timedEvent = ecore_timer_add(dueTime, + &StaticDispatchTimedEvent, + eventData); + + if (timedEvent == NULL) { + delete eventData; + delete abstractEventCall; + ThrowMsg(Exception::AddTimedEventFailed, + "Failed to add ECORE timed event"); + } + + LogPedantic("Timed wrapped event added"); + } else { + // Push immediate event onto ecore stack + Ecore_Event *event = ecore_event_add(m_eventId, + abstractEventCall, + &StaticDeleteEvent, + this); + + if (event == NULL) { + delete abstractEventCall; + ThrowMsg(Exception::AddEventFailed, "Failed to add ECORE event"); + } + + LogPedantic("Wrapped event added"); + } +} + +MainEventDispatcher& GetMainEventDispatcherInstance() +{ + return MainEventDispatcherSingleton::Instance(); +} +} +} // namespace DPL diff --git a/modules/event/src/model.cpp b/modules/event/src/model.cpp new file mode 100644 index 0000000..58e9a1b --- /dev/null +++ b/modules/event/src/model.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file model.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of model + */ +#include +#include + +namespace DPL { +namespace Event { +Model::~Model() +{} +} +} // namespace DPL diff --git a/modules/event/src/thread_event_dispatcher.cpp b/modules/event/src/thread_event_dispatcher.cpp new file mode 100644 index 0000000..7da99a2 --- /dev/null +++ b/modules/event/src/thread_event_dispatcher.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file thread_event_dispatcher.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of thread event dispatcher + */ +#include +#include +#include +#include + +namespace DPL { +namespace Event { +ThreadEventDispatcher::ThreadEventDispatcher() : + m_thread(NULL) +{} + +ThreadEventDispatcher::~ThreadEventDispatcher() +{} + +void ThreadEventDispatcher::SetThread(Thread *thread) +{ + m_thread = thread; +} + +void ThreadEventDispatcher::StaticEventDelete(void *event, void *userParam) +{ + AbstractEventCall *abstractEventCall = + static_cast(event); + ThreadEventDispatcher *This = + static_cast(userParam); + + LogPedantic("Received static event delete from thread"); + + Assert(abstractEventCall != NULL); + Assert(This != NULL); + + This->EventDelete(abstractEventCall); +} + +void ThreadEventDispatcher::StaticEventDispatch(void *event, void *userParam) +{ + AbstractEventCall *abstractEventCall = + static_cast(event); + ThreadEventDispatcher *This = + static_cast(userParam); + + LogPedantic("Received static event dispatch from thread"); + + Assert(abstractEventCall != NULL); + Assert(This != NULL); + + This->EventDispatch(abstractEventCall); +} + +void ThreadEventDispatcher::EventDelete(AbstractEventCall *abstractEventCall) +{ + LogPedantic("Deleting event"); + delete abstractEventCall; +} + +void ThreadEventDispatcher::EventDispatch(AbstractEventCall *abstractEventCall) +{ + LogPedantic("Dispatching event to event support"); + abstractEventCall->Call(); +} + +void ThreadEventDispatcher::AddEventCall(AbstractEventCall *abstractEventCall) +{ + // Thread must be set prior to call + Assert(m_thread != NULL); + + LogPedantic("Adding event to thread event loop"); + + // Call abstract event call in dedicated thread + m_thread->PushEvent(abstractEventCall, + &StaticEventDispatch, + &StaticEventDelete, + this); +} + +void ThreadEventDispatcher::AddTimedEventCall( + AbstractEventCall *abstractEventCall, + double dueTime) +{ + // Thread must be set prior to call + Assert(m_thread != NULL); + + LogPedantic("Adding timed event to thread event loop"); + + // Call abstract event call in dedicated thread + m_thread->PushTimedEvent(abstractEventCall, + dueTime, + &StaticEventDispatch, + &StaticEventDelete, + this); +} +} +} // namespace DPL diff --git a/modules/i18n/CMakeLists.txt b/modules/i18n/CMakeLists.txt new file mode 100644 index 0000000..9b1b175 --- /dev/null +++ b/modules/i18n/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY(dao) diff --git a/modules/i18n/dao/CMakeLists.txt b/modules/i18n/dao/CMakeLists.txt new file mode 100644 index 0000000..c7b5ada --- /dev/null +++ b/modules/i18n/dao/CMakeLists.txt @@ -0,0 +1,59 @@ +SET(TARGET_I18N_DAO_DB "Sqlite3DbI18n") + +ADD_CUSTOM_COMMAND( + OUTPUT ${CMAKE_BINARY_DIR}/modules/i18n/dao/database_checksum_i18n.h + COMMAND ${CMAKE_SOURCE_DIR}/modules/i18n/dao/orm/gen_db_md5.sh + ARGS ${CMAKE_BINARY_DIR}/modules/i18n/dao/database_checksum_i18n.h + ${CMAKE_SOURCE_DIR}/modules/i18n/dao/orm/iana_db + DEPENDS ${CMAKE_SOURCE_DIR}/modules/i18n/dao/orm/iana_db + ${CMAKE_SOURCE_DIR}/modules/i18n/dao/orm/gen_db_md5.sh + COMMENT "Generating WRT i18n database checksum" + ) + +ADD_CUSTOM_COMMAND( OUTPUT .wrt_i18n.db + COMMAND rm -f ${CMAKE_CURRENT_BINARY_DIR}/.wrt_i18n.db + COMMAND gcc -Wall -include ${CMAKE_BINARY_DIR}/modules/i18n/dao/database_checksum_i18n.h -I${PROJECT_SOURCE_DIR}/modules/db/include -I${PROJECT_SOURCE_DIR}/modules/i18n/dao/orm -E ${PROJECT_SOURCE_DIR}/modules/i18n/dao/orm/i18n_db_sql_generator.h | grep --invert-match "^#" > ${CMAKE_CURRENT_BINARY_DIR}/wrt_i18n_db.sql + COMMAND sqlite3 ${CMAKE_CURRENT_BINARY_DIR}/.wrt_i18n.db ".read ${CMAKE_CURRENT_BINARY_DIR}/wrt_i18n_db.sql" || rm -f ${CMAKE_CURRENT_BINARY_DIR}/.wrt_i18n.db + DEPENDS ${CMAKE_BINARY_DIR}/modules/i18n/dao/database_checksum_i18n.h ${PROJECT_SOURCE_DIR}/modules/i18n/dao/orm/i18n_db_sql_generator.h ${PROJECT_SOURCE_DIR}/modules/i18n/dao/orm/iana_db + ) + +ADD_CUSTOM_COMMAND( OUTPUT .wrt_i18n.db-journal + COMMAND touch + ARGS ${CMAKE_CURRENT_BINARY_DIR}/.wrt_i18n.db-journal + ) + +ADD_CUSTOM_TARGET(${TARGET_I18N_DAO_DB} ALL DEPENDS .wrt_i18n.db .wrt_i18n.db-journal) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/wrt_i18n_db.sql DESTINATION share/wrt-engine/) + +############################################################################### + +SET(I18N_DAO_INCLUDE_DIRS + ${PROJECT_SOURCE_DIR}/modules/i18n/dao/include + ${PROJECT_SOURCE_DIR}/modules/i18n/dao/orm + ${PROJECT_SOURCE_DIR}/modules/core/include + ${PROJECT_SOURCE_DIR}/modules/db/include + ${PROJECT_SOURCE_DIR}/modules/log/include +) + + +SET(I18N_DAO_RO_SOURCES + src/i18n_database.cpp + src/i18n_dao_read_only.cpp +) + +INCLUDE_DIRECTORIES(${I18N_DAO_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(SYSTEM ${I18N_DAO_DEPS_INCLUDE_DIRS}) + +ADD_LIBRARY(${TARGET_I18N_DAO_RO_LIB} SHARED ${I18N_DAO_RO_SOURCES}) +SET_TARGET_PROPERTIES(${TARGET_I18N_DAO_RO_LIB} PROPERTIES SOVERSION ${API_VERSION} VERSION ${VERSION}) +SET_TARGET_PROPERTIES(${TARGET_I18N_DAO_RO_LIB} PROPERTIES COMPILE_FLAGS "-include ${CMAKE_BINARY_DIR}/modules/i18n/dao/database_checksum_i18n.h") +TARGET_LINK_LIBRARIES(${TARGET_I18N_DAO_RO_LIB} ${TARGET_DPL_DB_EFL}) +ADD_DEPENDENCIES(${TARGET_I18N_DAO_RO_LIB} ${TARGET_I18N_DAO_DB}) + +INSTALL(TARGETS ${TARGET_I18N_DAO_RO_LIB} DESTINATION lib) + +INSTALL(FILES + include/wrt-commons/i18n-dao-ro/i18n_database.h + include/wrt-commons/i18n-dao-ro/i18n_dao_read_only.h + DESTINATION include/dpl-efl/wrt-commons/i18n-dao-ro +) diff --git a/modules/i18n/dao/include/wrt-commons/i18n-dao-ro/i18n_dao_read_only.h b/modules/i18n/dao/include/wrt-commons/i18n-dao-ro/i18n_dao_read_only.h new file mode 100644 index 0000000..7e8ef9d --- /dev/null +++ b/modules/i18n/dao/include/wrt-commons/i18n-dao-ro/i18n_dao_read_only.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of i18n dao namespace. + * + * @file i18n_dao_read_only.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of i18n dao. + */ + +#ifndef _I18N_DAO_READ_ONLY_H_ +#define _I18N_DAO_READ_ONLY_H_ + +#include + +namespace I18n { +namespace DB { +namespace I18nDAOReadOnly { +bool IsValidSubTag(const DPL::String& tag, int type); +} // namespace I18nDAOReadOnly +} // namespace DB +} // namespace I18n + +#endif // _I18N_DAO_READ_ONLY_H_ + diff --git a/modules/i18n/dao/include/wrt-commons/i18n-dao-ro/i18n_database.h b/modules/i18n/dao/include/wrt-commons/i18n-dao-ro/i18n_database.h new file mode 100644 index 0000000..3492f63 --- /dev/null +++ b/modules/i18n/dao/include/wrt-commons/i18n-dao-ro/i18n_database.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _I18N_DATABASE_H_ +#define _I18N_DATABASE_H_ + +#include +#include +#include + +namespace I18n { +namespace DB { +namespace Interface { +void attachDatabaseRO(); +void detachDatabase(); + +extern DPL::Mutex g_dbQueriesMutex; +extern DPL::DB::ThreadDatabaseSupport g_dbInterface; +} // namespace Interface +} // namespace DB +} // namespace I18n + +#define I18N_DB_INTERNAL(tlsCommand, InternalType) \ + static DPL::ThreadLocalVariable *tlsCommand##Ptr = NULL; \ + { \ + DPL::Mutex::ScopedLock lock( \ + &I18n::DB::Interface::g_dbQueriesMutex); \ + if (!tlsCommand##Ptr) { \ + static DPL::ThreadLocalVariable tmp; \ + tlsCommand##Ptr = &tmp; \ + } \ + } \ + DPL::ThreadLocalVariable &tlsCommand = *tlsCommand##Ptr; \ + if (tlsCommand.IsNull()) \ + { \ + tlsCommand = InternalType(&I18n::DB::Interface::g_dbInterface); \ + } + +#define I18N_DB_SELECT(name, type) \ + I18N_DB_INTERNAL(name, type::Select) + +#endif /* _I18N_DATABASE_H_ */ + diff --git a/modules/i18n/dao/orm/gen_db_md5.sh b/modules/i18n/dao/orm/gen_db_md5.sh new file mode 100755 index 0000000..22c2530 --- /dev/null +++ b/modules/i18n/dao/orm/gen_db_md5.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CHECKSUM=`cat ${2} ${3} 2>/dev/null | md5sum 2>/dev/null | cut -d\ -f1 2>/dev/null` +echo "#define DB_CHECKSUM DB_VERSION_${CHECKSUM}" > ${1} +echo "#define DB_CHECKSUM_STR \"DB_VERSION_${CHECKSUM}\"" >> ${1} + diff --git a/modules/i18n/dao/orm/i18n_db_definitions b/modules/i18n/dao/orm/i18n_db_definitions new file mode 100644 index 0000000..ee94c0a --- /dev/null +++ b/modules/i18n/dao/orm/i18n_db_definitions @@ -0,0 +1,6 @@ +DATABASE_START(i18n) + +#include "iana_db" +#include "version_db" + +DATABASE_END() diff --git a/modules/i18n/dao/orm/i18n_db_sql_generator.h b/modules/i18n/dao/orm/i18n_db_sql_generator.h new file mode 100644 index 0000000..d8f326d --- /dev/null +++ b/modules/i18n/dao/orm/i18n_db_sql_generator.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file i18n_db_sql_generator.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL + * input file from database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. +#include + +#include "i18n_db_definitions" diff --git a/modules/i18n/dao/orm/iana_db b/modules/i18n/dao/orm/iana_db new file mode 100644 index 0000000..ffd41ea --- /dev/null +++ b/modules/i18n/dao/orm/iana_db @@ -0,0 +1,8957 @@ +SQL(BEGIN IMMEDIATE TRANSACTION;) +CREATE_TABLE(iana_records) + COLUMN_NOT_NULL(REC_ID, INT,) + COLUMN_NOT_NULL(TYPE, INT,) + COLUMN(TAG, VARCHAR(256),) + COLUMN(SUBTAG, VARCHAR(256),) + COLUMN(DESCRIPTION, VARCHAR(256),) + COLUMN(ADDED, VARCHAR(256),) + COLUMN(DEPRECATED, INT,) + COLUMN(PREFERRED_VALUE, INT,) + COLUMN(PREFIX, VARCHAR(256),) + COLUMN(SUPPRESS_SCRIPT, VARCHAR(256),) + COLUMN(MACRO_LANGUAGE, VARCHAR(256),) + COLUMN(SCOPE, VARCHAR(256),) + COLUMN(COMMENTS, VARCHAR(256),) +CREATE_TABLE_END() +SQL( +INSERT INTO "iana_records" VALUES(0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1,0,NULL,'aa','afar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2,0,NULL,'ab','abkhazian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3,0,NULL,'ae','avestan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4,0,NULL,'af','afrikaans','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5,0,NULL,'ak','akan','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(6,0,NULL,'am','amharic','1129420800',NULL,NULL,NULL,'ethi',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7,0,NULL,'an','aragonese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8,0,NULL,'ar','arabic','1129420800',NULL,NULL,NULL,'arab',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(9,0,NULL,'as','assamese','1129420800',NULL,NULL,NULL,'beng',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(10,0,NULL,'av','avaric','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(11,0,NULL,'ay','aymara','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(12,0,NULL,'az','azerbaijani','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(13,0,NULL,'ba','bashkir','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(14,0,NULL,'be','belarusian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(15,0,NULL,'bg','bulgarian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(16,0,NULL,'bh','bihari languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(17,0,NULL,'bi','bislama','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(18,0,NULL,'bm','bambara','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(19,0,NULL,'bn','bengali','1129420800',NULL,NULL,NULL,'beng',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(20,0,NULL,'bo','tibetan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(21,0,NULL,'br','breton','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(22,0,NULL,'bs','bosnian','1129420800',NULL,NULL,NULL,'latn','sh',NULL,NULL); +INSERT INTO "iana_records" VALUES(23,0,NULL,'ca','catalan','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(23,0,NULL,'ca','valencian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(24,0,NULL,'ce','chechen','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(25,0,NULL,'ch','chamorro','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(26,0,NULL,'co','corsican','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(27,0,NULL,'cr','cree','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(28,0,NULL,'cs','czech','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(29,0,NULL,'cu','church slavic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(29,0,NULL,'cu','church slavonic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(29,0,NULL,'cu','old bulgarian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(29,0,NULL,'cu','old church slavonic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(29,0,NULL,'cu','old slavonic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(30,0,NULL,'cv','chuvash','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(31,0,NULL,'cy','welsh','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(32,0,NULL,'da','danish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(33,0,NULL,'de','german','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(34,0,NULL,'dv','dhivehi','1129420800',NULL,NULL,NULL,'thaa',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(34,0,NULL,'dv','divehi','1129420800',NULL,NULL,NULL,'thaa',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(34,0,NULL,'dv','maldivian','1129420800',NULL,NULL,NULL,'thaa',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(35,0,NULL,'dz','dzongkha','1129420800',NULL,NULL,NULL,'tibt',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(36,0,NULL,'ee','ewe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(37,0,NULL,'el','modern greek (1453-)','1129420800',NULL,NULL,NULL,'grek',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(38,0,NULL,'en','english','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(39,0,NULL,'eo','esperanto','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(40,0,NULL,'es','castilian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(40,0,NULL,'es','spanish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(41,0,NULL,'et','estonian','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(42,0,NULL,'eu','basque','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(43,0,NULL,'fa','persian','1129420800',NULL,NULL,NULL,'arab',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(44,0,NULL,'ff','fulah','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(45,0,NULL,'fi','finnish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(46,0,NULL,'fj','fijian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(47,0,NULL,'fo','faroese','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(48,0,NULL,'fr','french','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(49,0,NULL,'fy','western frisian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(50,0,NULL,'ga','irish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(51,0,NULL,'gd','gaelic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(51,0,NULL,'gd','scottish gaelic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(52,0,NULL,'gl','galician','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(53,0,NULL,'gn','guarani','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(54,0,NULL,'gu','gujarati','1129420800',NULL,NULL,NULL,'gujr',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(55,0,NULL,'gv','manx','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(56,0,NULL,'ha','hausa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(57,0,NULL,'he','hebrew','1129420800',NULL,NULL,NULL,'hebr',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(58,0,NULL,'hi','hindi','1129420800',NULL,NULL,NULL,'deva',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(59,0,NULL,'ho','hiri motu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(60,0,NULL,'hr','croatian','1129420800',NULL,NULL,NULL,'latn','sh',NULL,NULL); +INSERT INTO "iana_records" VALUES(61,0,NULL,'ht','haitian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(61,0,NULL,'ht','haitian creole','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(62,0,NULL,'hu','hungarian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(63,0,NULL,'hy','armenian','1129420800',NULL,NULL,NULL,'armn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(64,0,NULL,'hz','herero','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(65,0,NULL,'ia','interlingua (international auxiliary language association)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(66,0,NULL,'id','indonesian','1129420800',NULL,NULL,NULL,'latn','ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(67,0,NULL,'ie','interlingue','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(67,0,NULL,'ie','occidental','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(68,0,NULL,'ig','igbo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(69,0,NULL,'ii','nuosu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(69,0,NULL,'ii','sichuan yi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(70,0,NULL,'ik','inupiaq','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(71,0,NULL,'in','indonesian','1129420800',599616000,'id',NULL,'latn','ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(72,0,NULL,'io','ido','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(73,0,NULL,'is','icelandic','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(74,0,NULL,'it','italian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(75,0,NULL,'iu','inuktitut','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(76,0,NULL,'iw','hebrew','1129420800',599616000,'he',NULL,'hebr',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(77,0,NULL,'ja','japanese','1129420800',NULL,NULL,NULL,'jpan',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(78,0,NULL,'ji','yiddish','1129420800',599616000,'yi',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(79,0,NULL,'jv','javanese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(80,0,NULL,'jw','javanese','1129420800',997660800,'jv',NULL,NULL,NULL,NULL,'published by error in table 1 of iso 639:1988'); +INSERT INTO "iana_records" VALUES(81,0,NULL,'ka','georgian','1129420800',NULL,NULL,NULL,'geor',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(82,0,NULL,'kg','kongo','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(83,0,NULL,'ki','gikuyu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(83,0,NULL,'ki','kikuyu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(84,0,NULL,'kj','kuanyama','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(84,0,NULL,'kj','kwanyama','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(85,0,NULL,'kk','kazakh','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(86,0,NULL,'kl','greenlandic','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(86,0,NULL,'kl','kalaallisut','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(87,0,NULL,'km','central khmer','1129420800',NULL,NULL,NULL,'khmr',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(88,0,NULL,'kn','kannada','1129420800',NULL,NULL,NULL,'knda',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(89,0,NULL,'ko','korean','1129420800',NULL,NULL,NULL,'kore',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(90,0,NULL,'kr','kanuri','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(91,0,NULL,'ks','kashmiri','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(92,0,NULL,'ku','kurdish','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(93,0,NULL,'kv','komi','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(94,0,NULL,'kw','cornish','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(95,0,NULL,'ky','kirghiz','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(95,0,NULL,'ky','kyrgyz','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(96,0,NULL,'la','latin','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(97,0,NULL,'lb','letzeburgesch','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(97,0,NULL,'lb','luxembourgish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(98,0,NULL,'lg','ganda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(99,0,NULL,'li','limburgan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(99,0,NULL,'li','limburger','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(99,0,NULL,'li','limburgish','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(100,0,NULL,'ln','lingala','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(101,0,NULL,'lo','lao','1129420800',NULL,NULL,NULL,'laoo',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(102,0,NULL,'lt','lithuanian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(103,0,NULL,'lu','luba-katanga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(104,0,NULL,'lv','latvian','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(105,0,NULL,'mg','malagasy','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(106,0,NULL,'mh','marshallese','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(107,0,NULL,'mi','maori','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(108,0,NULL,'mk','macedonian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(109,0,NULL,'ml','malayalam','1129420800',NULL,NULL,NULL,'mlym',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(110,0,NULL,'mn','mongolian','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(111,0,NULL,'mo','moldavian','1129420800',1227312000,'ro',NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(111,0,NULL,'mo','moldovan','1129420800',1227312000,'ro',NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(112,0,NULL,'mr','marathi','1129420800',NULL,NULL,NULL,'deva',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(113,0,NULL,'ms','malay (macrolanguage)','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(114,0,NULL,'mt','maltese','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(115,0,NULL,'my','burmese','1129420800',NULL,NULL,NULL,'mymr',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(116,0,NULL,'na','nauru','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(117,0,NULL,'nb','norwegian bokmål','1129420800',NULL,NULL,NULL,'latn','no',NULL,NULL); +INSERT INTO "iana_records" VALUES(118,0,NULL,'nd','north ndebele','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(119,0,NULL,'ne','nepali','1129420800',NULL,NULL,NULL,'deva',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(120,0,NULL,'ng','ndonga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(121,0,NULL,'nl','dutch','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(121,0,NULL,'nl','flemish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(122,0,NULL,'nn','norwegian nynorsk','1129420800',NULL,NULL,NULL,'latn','no',NULL,NULL); +INSERT INTO "iana_records" VALUES(123,0,NULL,'no','norwegian','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(124,0,NULL,'nr','south ndebele','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(125,0,NULL,'nv','navaho','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(125,0,NULL,'nv','navajo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(126,0,NULL,'ny','chewa','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(126,0,NULL,'ny','chichewa','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(126,0,NULL,'ny','nyanja','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(127,0,NULL,'oc','occitan (post 1500)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(128,0,NULL,'oj','ojibwa','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(129,0,NULL,'om','oromo','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(130,0,NULL,'or','oriya','1129420800',NULL,NULL,NULL,'orya',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(131,0,NULL,'os','ossetian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(131,0,NULL,'os','ossetic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(132,0,NULL,'pa','panjabi','1129420800',NULL,NULL,NULL,'guru',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(132,0,NULL,'pa','punjabi','1129420800',NULL,NULL,NULL,'guru',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(133,0,NULL,'pi','pali','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(134,0,NULL,'pl','polish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(135,0,NULL,'ps','pashto','1129420800',NULL,NULL,NULL,'arab',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(135,0,NULL,'ps','pushto','1129420800',NULL,NULL,NULL,'arab',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(136,0,NULL,'pt','portuguese','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(137,0,NULL,'qu','quechua','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(138,0,NULL,'rm','romansh','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(139,0,NULL,'rn','rundi','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(140,0,NULL,'ro','moldavian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(140,0,NULL,'ro','moldovan','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(140,0,NULL,'ro','romanian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(141,0,NULL,'ru','russian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(142,0,NULL,'rw','kinyarwanda','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(143,0,NULL,'sa','sanskrit','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(144,0,NULL,'sc','sardinian','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(145,0,NULL,'sd','sindhi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(146,0,NULL,'se','northern sami','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(147,0,NULL,'sg','sango','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(148,0,NULL,'sh','serbo-croatian','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage','sr, hr, bs are preferred for most modern uses'); +INSERT INTO "iana_records" VALUES(149,0,NULL,'si','sinhala','1129420800',NULL,NULL,NULL,'sinh',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(149,0,NULL,'si','sinhalese','1129420800',NULL,NULL,NULL,'sinh',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(150,0,NULL,'sk','slovak','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(151,0,NULL,'sl','slovenian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(152,0,NULL,'sm','samoan','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(153,0,NULL,'sn','shona','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(154,0,NULL,'so','somali','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(155,0,NULL,'sq','albanian','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(156,0,NULL,'sr','serbian','1129420800',NULL,NULL,NULL,NULL,'sh',NULL,NULL); +INSERT INTO "iana_records" VALUES(157,0,NULL,'ss','swati','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(158,0,NULL,'st','southern sotho','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(159,0,NULL,'su','sundanese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(160,0,NULL,'sv','swedish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(161,0,NULL,'sw','swahili (macrolanguage)','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(162,0,NULL,'ta','tamil','1129420800',NULL,NULL,NULL,'taml',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(163,0,NULL,'te','telugu','1129420800',NULL,NULL,NULL,'telu',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(164,0,NULL,'tg','tajik','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(165,0,NULL,'th','thai','1129420800',NULL,NULL,NULL,'thai',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(166,0,NULL,'ti','tigrinya','1129420800',NULL,NULL,NULL,'ethi',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(167,0,NULL,'tk','turkmen','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(168,0,NULL,'tl','tagalog','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(169,0,NULL,'tn','tswana','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(170,0,NULL,'to','tonga (tonga islands)','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(171,0,NULL,'tr','turkish','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(172,0,NULL,'ts','tsonga','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(173,0,NULL,'tt','tatar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(174,0,NULL,'tw','twi','1129420800',NULL,NULL,NULL,NULL,'ak',NULL,NULL); +INSERT INTO "iana_records" VALUES(175,0,NULL,'ty','tahitian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(176,0,NULL,'ug','uighur','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(176,0,NULL,'ug','uyghur','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(177,0,NULL,'uk','ukrainian','1129420800',NULL,NULL,NULL,'cyrl',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(178,0,NULL,'ur','urdu','1129420800',NULL,NULL,NULL,'arab',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(179,0,NULL,'uz','uzbek','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(180,0,NULL,'ve','venda','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(181,0,NULL,'vi','vietnamese','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(182,0,NULL,'vo','volapük','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(183,0,NULL,'wa','walloon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(184,0,NULL,'wo','wolof','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(185,0,NULL,'xh','xhosa','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(186,0,NULL,'yi','yiddish','1129420800',NULL,NULL,NULL,'hebr',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(187,0,NULL,'yo','yoruba','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(188,0,NULL,'za','chuang','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(188,0,NULL,'za','zhuang','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(189,0,NULL,'zh','chinese','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(190,0,NULL,'zu','zulu','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(191,0,NULL,'aaa','ghotuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(192,0,NULL,'aab','alumu-tesu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(193,0,NULL,'aac','ari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(194,0,NULL,'aad','amal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(195,0,NULL,'aae','arbëreshë albanian','1248825600',NULL,NULL,NULL,NULL,'sq',NULL,NULL); +INSERT INTO "iana_records" VALUES(196,0,NULL,'aaf','aranadan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(197,0,NULL,'aag','ambrak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(198,0,NULL,'aah','abu'' arapesh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(199,0,NULL,'aai','arifama-miniafia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(200,0,NULL,'aak','ankave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(201,0,NULL,'aal','afade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(202,0,NULL,'aam','aramanik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(203,0,NULL,'aan','anambé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(204,0,NULL,'aao','algerian saharan arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(205,0,NULL,'aap','pará arára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(206,0,NULL,'aaq','eastern abnaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(207,0,NULL,'aas','aasáx','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(208,0,NULL,'aat','arvanitika albanian','1248825600',NULL,NULL,NULL,NULL,'sq',NULL,NULL); +INSERT INTO "iana_records" VALUES(209,0,NULL,'aau','abau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(210,0,NULL,'aav','austro-asiatic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(211,0,NULL,'aaw','solong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(212,0,NULL,'aax','mandobo atas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(213,0,NULL,'aaz','amarasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(214,0,NULL,'aba','abé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(215,0,NULL,'abb','bankon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(216,0,NULL,'abc','ambala ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(217,0,NULL,'abd','manide','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(218,0,NULL,'abe','western abnaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(219,0,NULL,'abf','abai sungai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(220,0,NULL,'abg','abaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(221,0,NULL,'abh','tajiki arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(222,0,NULL,'abi','abidji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(223,0,NULL,'abj','aka-bea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(224,0,NULL,'abl','lampung nyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(225,0,NULL,'abm','abanyom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(226,0,NULL,'abn','abua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(227,0,NULL,'abo','abon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(228,0,NULL,'abp','abellen ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(229,0,NULL,'abq','abaza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(230,0,NULL,'abr','abron','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(231,0,NULL,'abs','ambonese malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(232,0,NULL,'abt','ambulas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(233,0,NULL,'abu','abure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(234,0,NULL,'abv','baharna arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(235,0,NULL,'abw','pal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(236,0,NULL,'abx','inabaknon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(237,0,NULL,'aby','aneme wake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(238,0,NULL,'abz','abui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(239,0,NULL,'aca','achagua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(240,0,NULL,'acb','Áncá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(241,0,NULL,'acd','gikyode','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(242,0,NULL,'ace','achinese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(243,0,NULL,'acf','saint lucian creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(244,0,NULL,'ach','acoli','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(245,0,NULL,'aci','aka-cari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(246,0,NULL,'ack','aka-kora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(247,0,NULL,'acl','akar-bale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(248,0,NULL,'acm','mesopotamian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(249,0,NULL,'acn','achang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(250,0,NULL,'acp','eastern acipa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(251,0,NULL,'acq','ta''izzi-adeni arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(252,0,NULL,'acr','achi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(253,0,NULL,'acs','acroá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(254,0,NULL,'act','achterhoeks','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(255,0,NULL,'acu','achuar-shiwiar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(256,0,NULL,'acv','achumawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(257,0,NULL,'acw','hijazi arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(258,0,NULL,'acx','omani arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(259,0,NULL,'acy','cypriot arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(260,0,NULL,'acz','acheron','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(261,0,NULL,'ada','adangme','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(262,0,NULL,'adb','adabe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(263,0,NULL,'add','dzodinka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(264,0,NULL,'ade','adele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(265,0,NULL,'adf','dhofari arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(266,0,NULL,'adg','andegerebinha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(267,0,NULL,'adh','adhola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(268,0,NULL,'adi','adi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(269,0,NULL,'adj','adioukrou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(270,0,NULL,'adl','galo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(271,0,NULL,'adn','adang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(272,0,NULL,'ado','abu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(273,0,NULL,'adp','adap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(274,0,NULL,'adq','adangbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(275,0,NULL,'adr','adonara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(276,0,NULL,'ads','adamorobe sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(277,0,NULL,'adt','adnyamathanha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(278,0,NULL,'adu','aduge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(279,0,NULL,'adw','amundava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(280,0,NULL,'adx','amdo tibetan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(281,0,NULL,'ady','adygei','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(281,0,NULL,'ady','adyghe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(282,0,NULL,'adz','adzera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(283,0,NULL,'aea','areba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(284,0,NULL,'aeb','tunisian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(285,0,NULL,'aec','saidi arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(286,0,NULL,'aed','argentine sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(287,0,NULL,'aee','northeast pashayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(288,0,NULL,'aek','haeke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(289,0,NULL,'ael','ambele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(290,0,NULL,'aem','arem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(291,0,NULL,'aen','armenian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(292,0,NULL,'aeq','aer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(293,0,NULL,'aer','eastern arrernte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(294,0,NULL,'aes','alsea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(295,0,NULL,'aeu','akeu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(296,0,NULL,'aew','ambakich','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(297,0,NULL,'aey','amele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(298,0,NULL,'aez','aeka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(299,0,NULL,'afa','afro-asiatic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(300,0,NULL,'afb','gulf arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(301,0,NULL,'afd','andai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(302,0,NULL,'afe','putukwam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(303,0,NULL,'afg','afghan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(304,0,NULL,'afh','afrihili','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(305,0,NULL,'afi','akrukay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(306,0,NULL,'afk','nanubae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(307,0,NULL,'afn','defaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(308,0,NULL,'afo','eloyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(309,0,NULL,'afp','tapei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(310,0,NULL,'afs','afro-seminole creole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(311,0,NULL,'aft','afitti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(312,0,NULL,'afu','awutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(313,0,NULL,'afz','obokuitai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(314,0,NULL,'aga','aguano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(315,0,NULL,'agb','legbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(316,0,NULL,'agc','agatu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(317,0,NULL,'agd','agarabi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(318,0,NULL,'age','angal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(319,0,NULL,'agf','arguni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(320,0,NULL,'agg','angor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(321,0,NULL,'agh','ngelima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(322,0,NULL,'agi','agariya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(323,0,NULL,'agj','argobba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(324,0,NULL,'agk','isarog agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(325,0,NULL,'agl','fembe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(326,0,NULL,'agm','angaataha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(327,0,NULL,'agn','agutaynen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(328,0,NULL,'ago','tainae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(329,0,NULL,'agp','paranan','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see apf, prf'); +INSERT INTO "iana_records" VALUES(330,0,NULL,'agq','aghem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(331,0,NULL,'agr','aguaruna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(332,0,NULL,'ags','esimbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(333,0,NULL,'agt','central cagayan agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(334,0,NULL,'agu','aguacateco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(335,0,NULL,'agv','remontado dumagat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(336,0,NULL,'agw','kahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(337,0,NULL,'agx','aghul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(338,0,NULL,'agy','southern alta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(339,0,NULL,'agz','mt. iriga agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(340,0,NULL,'aha','ahanta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(341,0,NULL,'ahb','axamb','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(342,0,NULL,'ahg','qimant','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(343,0,NULL,'ahh','aghu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(344,0,NULL,'ahi','tiagbamrin aizi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(345,0,NULL,'ahk','akha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(346,0,NULL,'ahl','igo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(347,0,NULL,'ahm','mobumrin aizi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(348,0,NULL,'ahn','Àhàn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(349,0,NULL,'aho','ahom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(350,0,NULL,'ahp','aproumu aizi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(351,0,NULL,'ahr','ahirani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(352,0,NULL,'ahs','ashe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(353,0,NULL,'aht','ahtena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(354,0,NULL,'aia','arosi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(355,0,NULL,'aib','ainu (china)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(356,0,NULL,'aic','ainbai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(357,0,NULL,'aid','alngith','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(358,0,NULL,'aie','amara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(359,0,NULL,'aif','agi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(360,0,NULL,'aig','antigua and barbuda creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(361,0,NULL,'aih','ai-cham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(362,0,NULL,'aii','assyrian neo-aramaic','1248825600',NULL,NULL,NULL,NULL,'syr',NULL,NULL); +INSERT INTO "iana_records" VALUES(363,0,NULL,'aij','lishanid noshan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(364,0,NULL,'aik','ake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(365,0,NULL,'ail','aimele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(366,0,NULL,'aim','aimol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(367,0,NULL,'ain','ainu (japan)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(368,0,NULL,'aio','aiton','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(369,0,NULL,'aip','burumakok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(370,0,NULL,'aiq','aimaq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(371,0,NULL,'air','airoran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(372,0,NULL,'ais','nataoran amis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(373,0,NULL,'ait','arikem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(374,0,NULL,'aiw','aari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(375,0,NULL,'aix','aighon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(376,0,NULL,'aiy','ali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(377,0,NULL,'aja','aja (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(378,0,NULL,'ajg','aja (benin)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(379,0,NULL,'aji','ajië','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(380,0,NULL,'ajp','south levantine arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(381,0,NULL,'ajt','judeo-tunisian arabic','1248825600',NULL,NULL,NULL,NULL,'jrb',NULL,NULL); +INSERT INTO "iana_records" VALUES(382,0,NULL,'aju','judeo-moroccan arabic','1248825600',NULL,NULL,NULL,NULL,'jrb',NULL,NULL); +INSERT INTO "iana_records" VALUES(383,0,NULL,'ajw','ajawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(384,0,NULL,'ajz','amri karbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(385,0,NULL,'akb','batak angkola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(386,0,NULL,'akc','mpur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(387,0,NULL,'akd','ukpet-ehom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(388,0,NULL,'ake','akawaio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(389,0,NULL,'akf','akpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(390,0,NULL,'akg','anakalangu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(391,0,NULL,'akh','angal heneng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(392,0,NULL,'aki','aiome','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(393,0,NULL,'akj','aka-jeru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(394,0,NULL,'akk','akkadian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(395,0,NULL,'akl','aklanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(396,0,NULL,'akm','aka-bo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(397,0,NULL,'ako','akurio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(398,0,NULL,'akp','siwu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(399,0,NULL,'akq','ak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(400,0,NULL,'akr','araki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(401,0,NULL,'aks','akaselem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(402,0,NULL,'akt','akolet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(403,0,NULL,'aku','akum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(404,0,NULL,'akv','akhvakh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(405,0,NULL,'akw','akwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(406,0,NULL,'akx','aka-kede','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(407,0,NULL,'aky','aka-kol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(408,0,NULL,'akz','alabama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(409,0,NULL,'ala','alago','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(410,0,NULL,'alc','qawasqar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(411,0,NULL,'ald','alladian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(412,0,NULL,'ale','aleut','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(413,0,NULL,'alf','alege','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(414,0,NULL,'alg','algonquian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(415,0,NULL,'alh','alawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(416,0,NULL,'ali','amaimon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(417,0,NULL,'alj','alangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(418,0,NULL,'alk','alak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(419,0,NULL,'all','allar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(420,0,NULL,'alm','amblong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(421,0,NULL,'aln','gheg albanian','1248825600',NULL,NULL,NULL,NULL,'sq',NULL,NULL); +INSERT INTO "iana_records" VALUES(422,0,NULL,'alo','larike-wakasihu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(423,0,NULL,'alp','alune','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(424,0,NULL,'alq','algonquin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(425,0,NULL,'alr','alutor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(426,0,NULL,'als','tosk albanian','1248825600',NULL,NULL,NULL,NULL,'sq',NULL,NULL); +INSERT INTO "iana_records" VALUES(427,0,NULL,'alt','southern altai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(428,0,NULL,'alu','''are''are','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(429,0,NULL,'alv','atlantic-congo languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(430,0,NULL,'alw','alaba-k’abeena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(430,0,NULL,'alw','wanbasana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(431,0,NULL,'alx','amol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(432,0,NULL,'aly','alyawarr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(433,0,NULL,'alz','alur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(434,0,NULL,'ama','amanayé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(435,0,NULL,'amb','ambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(436,0,NULL,'amc','amahuaca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(437,0,NULL,'ame','yanesha''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(438,0,NULL,'amf','hamer-banna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(439,0,NULL,'amg','amarag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(440,0,NULL,'ami','amis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(441,0,NULL,'amj','amdang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(442,0,NULL,'amk','ambai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(443,0,NULL,'aml','war-jaintia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(444,0,NULL,'amm','ama (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(445,0,NULL,'amn','amanab','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(446,0,NULL,'amo','amo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(447,0,NULL,'amp','alamblak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(448,0,NULL,'amq','amahai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(449,0,NULL,'amr','amarakaeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(450,0,NULL,'ams','southern amami-oshima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(451,0,NULL,'amt','amto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(452,0,NULL,'amu','guerrero amuzgo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(453,0,NULL,'amv','ambelau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(454,0,NULL,'amw','western neo-aramaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(455,0,NULL,'amx','anmatyerre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(456,0,NULL,'amy','ami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(457,0,NULL,'amz','atampaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(458,0,NULL,'ana','andaqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(459,0,NULL,'anb','andoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(460,0,NULL,'anc','ngas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(461,0,NULL,'and','ansus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(462,0,NULL,'ane','xârâcùù','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(463,0,NULL,'anf','animere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(464,0,NULL,'ang','old english (ca. 450-1100)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(465,0,NULL,'anh','nend','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(466,0,NULL,'ani','andi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(467,0,NULL,'anj','anor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(468,0,NULL,'ank','goemai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(469,0,NULL,'anl','anu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(470,0,NULL,'anm','anal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(471,0,NULL,'ann','obolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(472,0,NULL,'ano','andoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(473,0,NULL,'anp','angika','1141776000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(474,0,NULL,'anq','jarawa (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(475,0,NULL,'anr','andh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(476,0,NULL,'ans','anserma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(477,0,NULL,'ant','antakarinya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(478,0,NULL,'anu','anuak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(479,0,NULL,'anv','denya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(480,0,NULL,'anw','anaang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(481,0,NULL,'anx','andra-hus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(482,0,NULL,'any','anyin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(483,0,NULL,'anz','anem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(484,0,NULL,'aoa','angolar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(485,0,NULL,'aob','abom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(486,0,NULL,'aoc','pemon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(487,0,NULL,'aod','andarum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(488,0,NULL,'aoe','angal enen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(489,0,NULL,'aof','bragat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(490,0,NULL,'aog','angoram','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(491,0,NULL,'aoh','arma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(492,0,NULL,'aoi','anindilyakwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(493,0,NULL,'aoj','mufian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(494,0,NULL,'aok','arhö','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(495,0,NULL,'aol','alor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(496,0,NULL,'aom','Ömie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(497,0,NULL,'aon','bumbita arapesh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(498,0,NULL,'aor','aore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(499,0,NULL,'aos','taikat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(500,0,NULL,'aot','a''tong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(501,0,NULL,'aox','atorada','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(502,0,NULL,'aoz','uab meto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(503,0,NULL,'apa','apache languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(504,0,NULL,'apb','sa''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(505,0,NULL,'apc','north levantine arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(506,0,NULL,'apd','sudanese arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(507,0,NULL,'ape','bukiyip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(508,0,NULL,'apf','pahanan agta','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(509,0,NULL,'apg','ampanang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(510,0,NULL,'aph','athpariya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(511,0,NULL,'api','apiaká','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(512,0,NULL,'apj','jicarilla apache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(513,0,NULL,'apk','kiowa apache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(514,0,NULL,'apl','lipan apache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(515,0,NULL,'apm','mescalero-chiricahua apache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(516,0,NULL,'apn','apinayé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(517,0,NULL,'apo','apalik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(518,0,NULL,'app','apma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(519,0,NULL,'apq','a-pucikwar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(520,0,NULL,'apr','arop-lokep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(521,0,NULL,'aps','arop-sissano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(522,0,NULL,'apt','apatani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(523,0,NULL,'apu','apurinã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(524,0,NULL,'apv','alapmunte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(525,0,NULL,'apw','western apache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(526,0,NULL,'apx','aputai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(527,0,NULL,'apy','apalaí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(528,0,NULL,'apz','safeyoka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(529,0,NULL,'aqa','alacalufan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(530,0,NULL,'aqc','archi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(531,0,NULL,'aqg','arigidi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(532,0,NULL,'aql','algic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(533,0,NULL,'aqm','atohwaim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(534,0,NULL,'aqn','northern alta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(535,0,NULL,'aqp','atakapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(536,0,NULL,'aqr','arhâ','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(537,0,NULL,'aqz','akuntsu','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(538,0,NULL,'arb','standard arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(539,0,NULL,'arc','imperial aramaic (700-300 bce)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(539,0,NULL,'arc','official aramaic (700-300 bce)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(540,0,NULL,'ard','arabana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(541,0,NULL,'are','western arrarnta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(542,0,NULL,'arh','arhuaco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(543,0,NULL,'ari','arikara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(544,0,NULL,'arj','arapaso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(545,0,NULL,'ark','arikapú','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(546,0,NULL,'arl','arabela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(547,0,NULL,'arn','mapuche','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(547,0,NULL,'arn','mapudungun','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(548,0,NULL,'aro','araona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(549,0,NULL,'arp','arapaho','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(550,0,NULL,'arq','algerian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(551,0,NULL,'arr','karo (brazil)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(552,0,NULL,'ars','najdi arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(553,0,NULL,'art','artificial languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(554,0,NULL,'aru','arawá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(554,0,NULL,'aru','aruá (amazonas state)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(555,0,NULL,'arv','arbore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(556,0,NULL,'arw','arawak','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(557,0,NULL,'arx','aruá (rodonia state)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(558,0,NULL,'ary','moroccan arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(559,0,NULL,'arz','egyptian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(560,0,NULL,'asa','asu (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(561,0,NULL,'asb','assiniboine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(562,0,NULL,'asc','casuarina coast asmat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(563,0,NULL,'asd','asas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(564,0,NULL,'ase','american sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(565,0,NULL,'asf','australian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(566,0,NULL,'asg','cishingini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(567,0,NULL,'ash','abishira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(568,0,NULL,'asi','buruwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(569,0,NULL,'asj','nsari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(570,0,NULL,'ask','ashkun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(571,0,NULL,'asl','asilulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(572,0,NULL,'asn','xingú asuriní','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(573,0,NULL,'aso','dano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(574,0,NULL,'asp','algerian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(575,0,NULL,'asq','austrian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(576,0,NULL,'asr','asuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(577,0,NULL,'ass','ipulo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(578,0,NULL,'ast','asturian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(578,0,NULL,'ast','asturleonese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(578,0,NULL,'ast','bable','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(578,0,NULL,'ast','leonese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(579,0,NULL,'asu','tocantins asurini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(580,0,NULL,'asv','asoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(581,0,NULL,'asw','australian aborigines sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(582,0,NULL,'asx','muratayak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(583,0,NULL,'asy','yaosakor asmat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(584,0,NULL,'asz','as','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(585,0,NULL,'ata','pele-ata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(586,0,NULL,'atb','zaiwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(587,0,NULL,'atc','atsahuaca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(588,0,NULL,'atd','ata manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(589,0,NULL,'ate','atemble','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(590,0,NULL,'atg','ivbie north-okpela-arhe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(591,0,NULL,'ath','athapascan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(592,0,NULL,'ati','attié','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(593,0,NULL,'atj','atikamekw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(594,0,NULL,'atk','ati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(595,0,NULL,'atl','mt. iraya agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(596,0,NULL,'atm','ata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(597,0,NULL,'atn','ashtiani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(598,0,NULL,'ato','atong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(599,0,NULL,'atp','pudtol atta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(600,0,NULL,'atq','aralle-tabulahan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(601,0,NULL,'atr','waimiri-atroari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(602,0,NULL,'ats','gros ventre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(603,0,NULL,'att','pamplona atta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(604,0,NULL,'atu','reel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(605,0,NULL,'atv','northern altai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(606,0,NULL,'atw','atsugewi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(607,0,NULL,'atx','arutani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(608,0,NULL,'aty','aneityum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(609,0,NULL,'atz','arta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(610,0,NULL,'aua','asumboa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(611,0,NULL,'aub','alugu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(612,0,NULL,'auc','waorani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(613,0,NULL,'aud','anuta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(614,0,NULL,'aue','=/kx''au//''ein','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(615,0,NULL,'auf','arauan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(616,0,NULL,'aug','aguna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(617,0,NULL,'auh','aushi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(618,0,NULL,'aui','anuki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(619,0,NULL,'auj','awjilah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(620,0,NULL,'auk','heyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(621,0,NULL,'aul','aulua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(622,0,NULL,'aum','asu (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(623,0,NULL,'aun','molmo one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(624,0,NULL,'auo','auyokawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(625,0,NULL,'aup','makayam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(626,0,NULL,'auq','anus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(626,0,NULL,'auq','korur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(627,0,NULL,'aur','aruek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(628,0,NULL,'aus','australian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(629,0,NULL,'aut','austral','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(630,0,NULL,'auu','auye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(631,0,NULL,'auw','awyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(632,0,NULL,'aux','aurá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(633,0,NULL,'auy','awiyaana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(634,0,NULL,'auz','uzbeki arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(635,0,NULL,'avb','avau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(636,0,NULL,'avd','alviri-vidari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(637,0,NULL,'avi','avikam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(638,0,NULL,'avk','kotava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(639,0,NULL,'avl','eastern egyptian bedawi arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(640,0,NULL,'avn','avatime','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(641,0,NULL,'avo','agavotaguerra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(642,0,NULL,'avs','aushiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(643,0,NULL,'avt','au','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(644,0,NULL,'avu','avokaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(645,0,NULL,'avv','avá-canoeiro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(646,0,NULL,'awa','awadhi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(647,0,NULL,'awb','awa (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(648,0,NULL,'awc','cicipu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(649,0,NULL,'awd','arawakan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(650,0,NULL,'awe','awetí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(651,0,NULL,'awh','awbono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(652,0,NULL,'awi','aekyom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(653,0,NULL,'awk','awabakal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(654,0,NULL,'awm','arawum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(655,0,NULL,'awn','awngi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(656,0,NULL,'awo','awak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(657,0,NULL,'awr','awera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(658,0,NULL,'aws','south awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(659,0,NULL,'awt','araweté','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(660,0,NULL,'awu','central awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(661,0,NULL,'awv','jair awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(662,0,NULL,'aww','awun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(663,0,NULL,'awx','awara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(664,0,NULL,'awy','edera awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(665,0,NULL,'axb','abipon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(666,0,NULL,'axg','mato grosso arára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(667,0,NULL,'axk','yaka (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(668,0,NULL,'axm','middle armenian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(669,0,NULL,'axx','xaragure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(670,0,NULL,'aya','awar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(671,0,NULL,'ayb','ayizo gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(672,0,NULL,'ayc','southern aymara','1248825600',NULL,NULL,NULL,NULL,'ay',NULL,NULL); +INSERT INTO "iana_records" VALUES(673,0,NULL,'ayd','ayabadhu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(674,0,NULL,'aye','ayere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(675,0,NULL,'ayg','ginyanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(676,0,NULL,'ayh','hadrami arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(677,0,NULL,'ayi','leyigha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(678,0,NULL,'ayk','akuku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(679,0,NULL,'ayl','libyan arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(680,0,NULL,'ayn','sanaani arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(681,0,NULL,'ayo','ayoreo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(682,0,NULL,'ayp','north mesopotamian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(683,0,NULL,'ayq','ayi (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(684,0,NULL,'ayr','central aymara','1248825600',NULL,NULL,NULL,NULL,'ay',NULL,NULL); +INSERT INTO "iana_records" VALUES(685,0,NULL,'ays','sorsogon ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(686,0,NULL,'ayt','magbukun ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(687,0,NULL,'ayu','ayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(688,0,NULL,'ayx','ayi (china)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(689,0,NULL,'ayy','tayabas ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(690,0,NULL,'ayz','mai brat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(691,0,NULL,'aza','azha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(692,0,NULL,'azb','south azerbaijani','1248825600',NULL,NULL,NULL,NULL,'az',NULL,NULL); +INSERT INTO "iana_records" VALUES(693,0,NULL,'azc','uto-aztecan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(694,0,NULL,'azg','san pedro amuzgos amuzgo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(695,0,NULL,'azj','north azerbaijani','1248825600',NULL,NULL,NULL,NULL,'az',NULL,NULL); +INSERT INTO "iana_records" VALUES(696,0,NULL,'azm','ipalapa amuzgo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(697,0,NULL,'azo','awing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(698,0,NULL,'azt','faire atta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(699,0,NULL,'azz','highland puebla nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(700,0,NULL,'baa','babatana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(701,0,NULL,'bab','bainouk-gunyuño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(702,0,NULL,'bac','badui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(703,0,NULL,'bad','banda languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(704,0,NULL,'bae','baré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(705,0,NULL,'baf','nubaca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(706,0,NULL,'bag','tuki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(707,0,NULL,'bah','bahamas creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(708,0,NULL,'bai','bamileke languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(709,0,NULL,'baj','barakai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(710,0,NULL,'bal','baluchi','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(711,0,NULL,'ban','balinese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(712,0,NULL,'bao','waimaha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(713,0,NULL,'bap','bantawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(714,0,NULL,'bar','bavarian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(715,0,NULL,'bas','basa (cameroon)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(716,0,NULL,'bat','baltic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(717,0,NULL,'bau','bada (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(718,0,NULL,'bav','vengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(719,0,NULL,'baw','bambili-bambui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(720,0,NULL,'bax','bamun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(721,0,NULL,'bay','batuley','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(722,0,NULL,'baz','tunen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(723,0,NULL,'bba','baatonum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(724,0,NULL,'bbb','barai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(725,0,NULL,'bbc','batak toba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(726,0,NULL,'bbd','bau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(727,0,NULL,'bbe','bangba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(728,0,NULL,'bbf','baibai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(729,0,NULL,'bbg','barama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(730,0,NULL,'bbh','bugan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(731,0,NULL,'bbi','barombi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(732,0,NULL,'bbj','ghomálá''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(733,0,NULL,'bbk','babanki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(734,0,NULL,'bbl','bats','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(735,0,NULL,'bbm','babango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(736,0,NULL,'bbn','uneapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(737,0,NULL,'bbo','konabéré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(737,0,NULL,'bbo','northern bobo madaré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(738,0,NULL,'bbp','west central banda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(739,0,NULL,'bbq','bamali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(740,0,NULL,'bbr','girawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(741,0,NULL,'bbs','bakpinka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(742,0,NULL,'bbt','mburku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(743,0,NULL,'bbu','kulung (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(744,0,NULL,'bbv','karnai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(745,0,NULL,'bbw','baba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(746,0,NULL,'bbx','bubia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(747,0,NULL,'bby','befang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(748,0,NULL,'bbz','babalia creole arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(749,0,NULL,'bca','central bai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(750,0,NULL,'bcb','bainouk-samik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(751,0,NULL,'bcc','southern balochi','1248825600',NULL,NULL,NULL,NULL,'bal',NULL,NULL); +INSERT INTO "iana_records" VALUES(752,0,NULL,'bcd','north babar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(753,0,NULL,'bce','bamenyam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(754,0,NULL,'bcf','bamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(755,0,NULL,'bcg','baga binari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(756,0,NULL,'bch','bariai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(757,0,NULL,'bci','baoulé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(758,0,NULL,'bcj','bardi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(759,0,NULL,'bck','bunaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(760,0,NULL,'bcl','central bicolano','1248825600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(761,0,NULL,'bcm','bannoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(762,0,NULL,'bcn','bali (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(763,0,NULL,'bco','kaluli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(764,0,NULL,'bcp','bali (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(765,0,NULL,'bcq','bench','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(766,0,NULL,'bcr','babine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(767,0,NULL,'bcs','kohumono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(768,0,NULL,'bct','bendi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(769,0,NULL,'bcu','awad bing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(770,0,NULL,'bcv','shoo-minda-nye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(771,0,NULL,'bcw','bana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(772,0,NULL,'bcy','bacama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(773,0,NULL,'bcz','bainouk-gunyaamolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(774,0,NULL,'bda','bayot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(775,0,NULL,'bdb','basap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(776,0,NULL,'bdc','emberá-baudó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(777,0,NULL,'bdd','bunama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(778,0,NULL,'bde','bade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(779,0,NULL,'bdf','biage','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(780,0,NULL,'bdg','bonggi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(781,0,NULL,'bdh','baka (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(782,0,NULL,'bdi','burun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(783,0,NULL,'bdj','bai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(784,0,NULL,'bdk','budukh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(785,0,NULL,'bdl','indonesian bajau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(786,0,NULL,'bdm','buduma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(787,0,NULL,'bdn','baldemu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(788,0,NULL,'bdo','morom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(789,0,NULL,'bdp','bende','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(790,0,NULL,'bdq','bahnar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(791,0,NULL,'bdr','west coast bajau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(792,0,NULL,'bds','burunge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(793,0,NULL,'bdt','bokoto','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(794,0,NULL,'bdu','oroko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(795,0,NULL,'bdv','bodo parja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(796,0,NULL,'bdw','baham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(797,0,NULL,'bdx','budong-budong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(798,0,NULL,'bdy','bandjalang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(799,0,NULL,'bdz','badeshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(800,0,NULL,'bea','beaver','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(801,0,NULL,'beb','bebele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(802,0,NULL,'bec','iceve-maci','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(803,0,NULL,'bed','bedoanas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(804,0,NULL,'bee','byangsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(805,0,NULL,'bef','benabena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(806,0,NULL,'beg','belait','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(807,0,NULL,'beh','biali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(808,0,NULL,'bei','bekati''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(809,0,NULL,'bej','bedawiyet','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(809,0,NULL,'bej','beja','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(810,0,NULL,'bek','bebeli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(811,0,NULL,'bem','bemba (zambia)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(812,0,NULL,'beo','beami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(813,0,NULL,'bep','besoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(814,0,NULL,'beq','beembe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(815,0,NULL,'ber','berber languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(816,0,NULL,'bes','besme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(817,0,NULL,'bet','guiberoua béte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(818,0,NULL,'beu','blagar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(819,0,NULL,'bev','daloa bété','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(820,0,NULL,'bew','betawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(821,0,NULL,'bex','jur modo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(822,0,NULL,'bey','beli (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(823,0,NULL,'bez','bena (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(824,0,NULL,'bfa','bari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(825,0,NULL,'bfb','pauri bareli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(826,0,NULL,'bfc','northern bai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(827,0,NULL,'bfd','bafut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(828,0,NULL,'bfe','betaf','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(828,0,NULL,'bfe','tena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(829,0,NULL,'bff','bofi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(830,0,NULL,'bfg','busang kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(831,0,NULL,'bfh','blafe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(832,0,NULL,'bfi','british sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(833,0,NULL,'bfj','bafanji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(834,0,NULL,'bfk','ban khor sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(835,0,NULL,'bfl','banda-ndélé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(836,0,NULL,'bfm','mmen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(837,0,NULL,'bfn','bunak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(838,0,NULL,'bfo','malba birifor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(839,0,NULL,'bfp','beba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(840,0,NULL,'bfq','badaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(841,0,NULL,'bfr','bazigar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(842,0,NULL,'bfs','southern bai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(843,0,NULL,'bft','balti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(844,0,NULL,'bfu','gahri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(845,0,NULL,'bfw','bondo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(846,0,NULL,'bfx','bantayanon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(847,0,NULL,'bfy','bagheli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(848,0,NULL,'bfz','mahasu pahari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(849,0,NULL,'bga','gwamhi-wuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(850,0,NULL,'bgb','bobongko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(851,0,NULL,'bgc','haryanvi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(852,0,NULL,'bgd','rathwi bareli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(853,0,NULL,'bge','bauria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(854,0,NULL,'bgf','bangandu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(855,0,NULL,'bgg','bugun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(856,0,NULL,'bgi','giangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(857,0,NULL,'bgj','bangolan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(858,0,NULL,'bgk','bit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(858,0,NULL,'bgk','buxinhua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(859,0,NULL,'bgl','bo (laos)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(860,0,NULL,'bgm','baga mboteni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(861,0,NULL,'bgn','western balochi','1248825600',NULL,NULL,NULL,NULL,'bal',NULL,NULL); +INSERT INTO "iana_records" VALUES(862,0,NULL,'bgo','baga koga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(863,0,NULL,'bgp','eastern balochi','1248825600',NULL,NULL,NULL,NULL,'bal',NULL,NULL); +INSERT INTO "iana_records" VALUES(864,0,NULL,'bgq','bagri','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(865,0,NULL,'bgr','bawm chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(866,0,NULL,'bgs','tagabawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(867,0,NULL,'bgt','bughotu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(868,0,NULL,'bgu','mbongno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(869,0,NULL,'bgv','warkay-bipim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(870,0,NULL,'bgw','bhatri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(871,0,NULL,'bgx','balkan gagauz turkish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(872,0,NULL,'bgy','benggoi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(873,0,NULL,'bgz','banggai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(874,0,NULL,'bha','bharia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(875,0,NULL,'bhb','bhili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(876,0,NULL,'bhc','biga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(877,0,NULL,'bhd','bhadrawahi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(878,0,NULL,'bhe','bhaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(879,0,NULL,'bhf','odiai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(880,0,NULL,'bhg','binandere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(881,0,NULL,'bhh','bukharic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(882,0,NULL,'bhi','bhilali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(883,0,NULL,'bhj','bahing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(884,0,NULL,'bhk','albay bicolano','1248825600',1268265600,NULL,NULL,NULL,'bik',NULL,'see fbl, lbl, rbl, ubl'); +INSERT INTO "iana_records" VALUES(885,0,NULL,'bhl','bimin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(886,0,NULL,'bhm','bathari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(887,0,NULL,'bhn','bohtan neo-aramaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(888,0,NULL,'bho','bhojpuri','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(889,0,NULL,'bhp','bima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(890,0,NULL,'bhq','tukang besi south','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(891,0,NULL,'bhr','bara malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(892,0,NULL,'bhs','buwal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(893,0,NULL,'bht','bhattiyali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(894,0,NULL,'bhu','bhunjia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(895,0,NULL,'bhv','bahau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(896,0,NULL,'bhw','biak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(897,0,NULL,'bhx','bhalay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(898,0,NULL,'bhy','bhele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(899,0,NULL,'bhz','bada (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(900,0,NULL,'bia','badimaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(901,0,NULL,'bib','bissa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(902,0,NULL,'bic','bikaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(903,0,NULL,'bid','bidiyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(904,0,NULL,'bie','bepour','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(905,0,NULL,'bif','biafada','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(906,0,NULL,'big','biangai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(907,0,NULL,'bij','vaghat-ya-bijim-legeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(908,0,NULL,'bik','bikol','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(909,0,NULL,'bil','bile','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(910,0,NULL,'bim','bimoba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(911,0,NULL,'bin','bini','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(911,0,NULL,'bin','edo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(912,0,NULL,'bio','nai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(913,0,NULL,'bip','bila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(914,0,NULL,'biq','bipi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(915,0,NULL,'bir','bisorio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(916,0,NULL,'bit','berinomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(917,0,NULL,'biu','biete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(918,0,NULL,'biv','southern birifor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(919,0,NULL,'biw','kol (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(920,0,NULL,'bix','bijori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(921,0,NULL,'biy','birhor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(922,0,NULL,'biz','baloi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(923,0,NULL,'bja','budza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(924,0,NULL,'bjb','banggarla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(925,0,NULL,'bjc','bariji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(926,0,NULL,'bjd','bandjigali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(927,0,NULL,'bje','biao-jiao mien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(928,0,NULL,'bjf','barzani jewish neo-aramaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(929,0,NULL,'bjg','bidyogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(930,0,NULL,'bjh','bahinemo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(931,0,NULL,'bji','burji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(932,0,NULL,'bjj','kanauji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(933,0,NULL,'bjk','barok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(934,0,NULL,'bjl','bulu (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(935,0,NULL,'bjm','bajelani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(936,0,NULL,'bjn','banjar','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(937,0,NULL,'bjo','mid-southern banda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(938,0,NULL,'bjq','southern betsimisaraka malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(939,0,NULL,'bjr','binumarien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(940,0,NULL,'bjs','bajan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(941,0,NULL,'bjt','balanta-ganja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(942,0,NULL,'bju','busuu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(943,0,NULL,'bjv','bedjond','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(944,0,NULL,'bjw','bakwé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(945,0,NULL,'bjx','banao itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(946,0,NULL,'bjy','bayali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(947,0,NULL,'bjz','baruga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(948,0,NULL,'bka','kyak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(949,0,NULL,'bkb','finallig','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see ebk, obk'); +INSERT INTO "iana_records" VALUES(950,0,NULL,'bkc','baka (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(951,0,NULL,'bkd','binukid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(951,0,NULL,'bkd','talaandig','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(952,0,NULL,'bkf','beeke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(953,0,NULL,'bkg','buraka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(954,0,NULL,'bkh','bakoko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(955,0,NULL,'bki','baki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(956,0,NULL,'bkj','pande','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(957,0,NULL,'bkk','brokskat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(958,0,NULL,'bkl','berik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(959,0,NULL,'bkm','kom (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(960,0,NULL,'bkn','bukitan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(961,0,NULL,'bko','kwa''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(962,0,NULL,'bkp','boko (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(963,0,NULL,'bkq','bakairí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(964,0,NULL,'bkr','bakumpai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(965,0,NULL,'bks','northern sorsoganon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(966,0,NULL,'bkt','boloki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(967,0,NULL,'bku','buhid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(968,0,NULL,'bkv','bekwarra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(969,0,NULL,'bkw','bekwil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(970,0,NULL,'bkx','baikeno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(971,0,NULL,'bky','bokyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(972,0,NULL,'bkz','bungku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(973,0,NULL,'bla','siksika','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(974,0,NULL,'blb','bilua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(975,0,NULL,'blc','bella coola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(976,0,NULL,'bld','bolango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(977,0,NULL,'ble','balanta-kentohe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(978,0,NULL,'blf','buol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(979,0,NULL,'blg','balau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(980,0,NULL,'blh','kuwaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(981,0,NULL,'bli','bolia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(982,0,NULL,'blj','bolongan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(983,0,NULL,'blk','pa''o karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(984,0,NULL,'bll','biloxi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(985,0,NULL,'blm','beli (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(986,0,NULL,'bln','southern catanduanes bicolano','1248825600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(987,0,NULL,'blo','anii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(988,0,NULL,'blp','blablanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(989,0,NULL,'blq','baluan-pam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(990,0,NULL,'blr','blang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(991,0,NULL,'bls','balaesang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(992,0,NULL,'blt','tai dam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(993,0,NULL,'blv','bolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(994,0,NULL,'blw','balangao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(995,0,NULL,'blx','mag-indi ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(996,0,NULL,'bly','notre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(997,0,NULL,'blz','balantak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(998,0,NULL,'bma','lame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(999,0,NULL,'bmb','bembe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1000,0,NULL,'bmc','biem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1001,0,NULL,'bmd','baga manduri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1002,0,NULL,'bme','limassa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1003,0,NULL,'bmf','bom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1004,0,NULL,'bmg','bamwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1005,0,NULL,'bmh','kein','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1006,0,NULL,'bmi','bagirmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1007,0,NULL,'bmj','bote-majhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1008,0,NULL,'bmk','ghayavi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1009,0,NULL,'bml','bomboli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1010,0,NULL,'bmm','northern betsimisaraka malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(1011,0,NULL,'bmn','bina (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1012,0,NULL,'bmo','bambalang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1013,0,NULL,'bmp','bulgebi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1014,0,NULL,'bmq','bomu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1015,0,NULL,'bmr','muinane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1016,0,NULL,'bms','bilma kanuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1017,0,NULL,'bmt','biao mon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1018,0,NULL,'bmu','burum-mindik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1019,0,NULL,'bmv','bum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1020,0,NULL,'bmw','bomwali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1021,0,NULL,'bmx','baimak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1022,0,NULL,'bmy','bemba (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1023,0,NULL,'bmz','baramu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1024,0,NULL,'bna','bonerate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1025,0,NULL,'bnb','bookan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1026,0,NULL,'bnc','bontok','1248825600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1027,0,NULL,'bnd','banda (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1028,0,NULL,'bne','bintauna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1029,0,NULL,'bnf','masiwang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1030,0,NULL,'bng','benga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1031,0,NULL,'bni','bangi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1032,0,NULL,'bnj','eastern tawbuid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1033,0,NULL,'bnk','bierebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1034,0,NULL,'bnl','boon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1035,0,NULL,'bnm','batanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1036,0,NULL,'bnn','bunun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1037,0,NULL,'bno','bantoanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1038,0,NULL,'bnp','bola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1039,0,NULL,'bnq','bantik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1040,0,NULL,'bnr','butmas-tur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1041,0,NULL,'bns','bundeli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1042,0,NULL,'bnt','bantu languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1043,0,NULL,'bnu','bentong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1044,0,NULL,'bnv','beneraf','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1044,0,NULL,'bnv','bonerif','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1044,0,NULL,'bnv','edwas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1045,0,NULL,'bnw','bisis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1046,0,NULL,'bnx','bangubangu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1047,0,NULL,'bny','bintulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1048,0,NULL,'bnz','beezen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1049,0,NULL,'boa','bora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1050,0,NULL,'bob','aweer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1051,0,NULL,'boe','mundabli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1052,0,NULL,'bof','bolon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1053,0,NULL,'bog','bamako sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1054,0,NULL,'boh','boma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1055,0,NULL,'boi','barbareño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1056,0,NULL,'boj','anjam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1057,0,NULL,'bok','bonjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1058,0,NULL,'bol','bole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1059,0,NULL,'bom','berom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1060,0,NULL,'bon','bine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1061,0,NULL,'boo','tiemacèwè bozo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1062,0,NULL,'bop','bonkiman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1063,0,NULL,'boq','bogaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1064,0,NULL,'bor','borôro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1065,0,NULL,'bot','bongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1066,0,NULL,'bou','bondei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1067,0,NULL,'bov','tuwuli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1068,0,NULL,'bow','rema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1069,0,NULL,'box','buamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1070,0,NULL,'boy','bodo (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1071,0,NULL,'boz','tiéyaxo bozo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1072,0,NULL,'bpa','dakaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1073,0,NULL,'bpb','barbacoas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1074,0,NULL,'bpd','banda-banda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1075,0,NULL,'bpg','bonggo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1076,0,NULL,'bph','botlikh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1077,0,NULL,'bpi','bagupi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1078,0,NULL,'bpj','binji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1079,0,NULL,'bpk','orowe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1080,0,NULL,'bpl','broome pearling lugger pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1081,0,NULL,'bpm','biyom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1082,0,NULL,'bpn','dzao min','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1083,0,NULL,'bpo','anasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1084,0,NULL,'bpp','kaure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1085,0,NULL,'bpq','banda malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1086,0,NULL,'bpr','koronadal blaan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1087,0,NULL,'bps','sarangani blaan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1088,0,NULL,'bpt','barrow point','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1089,0,NULL,'bpu','bongu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1090,0,NULL,'bpv','bian marind','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1091,0,NULL,'bpw','bo (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1092,0,NULL,'bpx','palya bareli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1093,0,NULL,'bpy','bishnupriya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1094,0,NULL,'bpz','bilba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1095,0,NULL,'bqa','tchumbuli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1096,0,NULL,'bqb','bagusa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1097,0,NULL,'bqc','boko (benin)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1098,0,NULL,'bqd','bung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1099,0,NULL,'bqf','baga kaloum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1100,0,NULL,'bqg','bago-kusuntu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1101,0,NULL,'bqh','baima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1102,0,NULL,'bqi','bakhtiari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1103,0,NULL,'bqj','bandial','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1104,0,NULL,'bqk','banda-mbrès','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1105,0,NULL,'bql','bilakura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1106,0,NULL,'bqm','wumboko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1107,0,NULL,'bqn','bulgarian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1108,0,NULL,'bqo','balo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1109,0,NULL,'bqp','busa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1110,0,NULL,'bqq','biritai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1111,0,NULL,'bqr','burusu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1112,0,NULL,'bqs','bosngun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1113,0,NULL,'bqt','bamukumbit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1114,0,NULL,'bqu','boguru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1115,0,NULL,'bqv','begbere-ejar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1116,0,NULL,'bqw','buru (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1117,0,NULL,'bqx','baangi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1118,0,NULL,'bqy','bengkala sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1119,0,NULL,'bqz','bakaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1120,0,NULL,'bra','braj','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1121,0,NULL,'brb','lave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1122,0,NULL,'brc','berbice creole dutch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1123,0,NULL,'brd','baraamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1124,0,NULL,'brf','bera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1125,0,NULL,'brg','baure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1126,0,NULL,'brh','brahui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1127,0,NULL,'bri','mokpwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1128,0,NULL,'brj','bieria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1129,0,NULL,'brk','birked','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1130,0,NULL,'brl','birwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1131,0,NULL,'brm','barambu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1132,0,NULL,'brn','boruca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1133,0,NULL,'bro','brokkat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1134,0,NULL,'brp','barapasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1135,0,NULL,'brq','breri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1136,0,NULL,'brr','birao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1137,0,NULL,'brs','baras','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1138,0,NULL,'brt','bitare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1139,0,NULL,'bru','eastern bru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1140,0,NULL,'brv','western bru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1141,0,NULL,'brw','bellari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1142,0,NULL,'brx','bodo (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1143,0,NULL,'bry','burui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1144,0,NULL,'brz','bilbil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1145,0,NULL,'bsa','abinomn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1146,0,NULL,'bsb','brunei bisaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1147,0,NULL,'bsc','bassari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1147,0,NULL,'bsc','oniyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1148,0,NULL,'bse','wushi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1149,0,NULL,'bsf','bauchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1150,0,NULL,'bsg','bashkardi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1151,0,NULL,'bsh','kati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1152,0,NULL,'bsi','bassossi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1153,0,NULL,'bsj','bangwinji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1154,0,NULL,'bsk','burushaski','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1155,0,NULL,'bsl','basa-gumna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1156,0,NULL,'bsm','busami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1157,0,NULL,'bsn','barasana-eduria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1158,0,NULL,'bso','buso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1159,0,NULL,'bsp','baga sitemu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1160,0,NULL,'bsq','bassa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1161,0,NULL,'bsr','bassa-kontagora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1162,0,NULL,'bss','akoose','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1163,0,NULL,'bst','basketo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1164,0,NULL,'bsu','bahonsuai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1165,0,NULL,'bsv','baga sobané','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1166,0,NULL,'bsw','baiso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1167,0,NULL,'bsx','yangkam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1168,0,NULL,'bsy','sabah bisaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1169,0,NULL,'bta','bata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1170,0,NULL,'btb','beti (cameroon)','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see beb, bum, bxp, eto, ewo, fan, mct'); +INSERT INTO "iana_records" VALUES(1171,0,NULL,'btc','bati (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1172,0,NULL,'btd','batak dairi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1173,0,NULL,'bte','gamo-ningi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1174,0,NULL,'btf','birgit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1175,0,NULL,'btg','gagnoa bété','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1176,0,NULL,'bth','biatah bidayuh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1177,0,NULL,'bti','burate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1178,0,NULL,'btj','bacanese malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(1179,0,NULL,'btk','batak languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1180,0,NULL,'btl','bhatola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1181,0,NULL,'btm','batak mandailing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1182,0,NULL,'btn','ratagnon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1183,0,NULL,'bto','rinconada bikol','1248825600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(1184,0,NULL,'btp','budibud','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1185,0,NULL,'btq','batek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1186,0,NULL,'btr','baetora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1187,0,NULL,'bts','batak simalungun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1188,0,NULL,'btt','bete-bendi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1189,0,NULL,'btu','batu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1190,0,NULL,'btv','bateri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1191,0,NULL,'btw','butuanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1192,0,NULL,'btx','batak karo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1193,0,NULL,'bty','bobot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1194,0,NULL,'btz','batak alas-kluet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1195,0,NULL,'bua','buriat','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1196,0,NULL,'bub','bua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1197,0,NULL,'buc','bushi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1198,0,NULL,'bud','ntcham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1199,0,NULL,'bue','beothuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1200,0,NULL,'buf','bushoong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1201,0,NULL,'bug','buginese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1202,0,NULL,'buh','younuo bunu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1203,0,NULL,'bui','bongili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1204,0,NULL,'buj','basa-gurmana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1205,0,NULL,'buk','bugawac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1206,0,NULL,'bum','bulu (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1207,0,NULL,'bun','sherbro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1208,0,NULL,'buo','terei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1209,0,NULL,'bup','busoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1210,0,NULL,'buq','brem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1211,0,NULL,'bus','bokobaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1212,0,NULL,'but','bungain','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1213,0,NULL,'buu','budu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1214,0,NULL,'buv','bun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1215,0,NULL,'buw','bubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1216,0,NULL,'bux','boghom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1217,0,NULL,'buy','bullom so','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1218,0,NULL,'buz','bukwen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1219,0,NULL,'bva','barein','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1220,0,NULL,'bvb','bube','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1221,0,NULL,'bvc','baelelea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1222,0,NULL,'bvd','baeggu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1223,0,NULL,'bve','berau malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(1224,0,NULL,'bvf','boor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1225,0,NULL,'bvg','bonkeng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1226,0,NULL,'bvh','bure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1227,0,NULL,'bvi','belanda viri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1228,0,NULL,'bvj','baan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1229,0,NULL,'bvk','bukat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1230,0,NULL,'bvl','bolivian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1231,0,NULL,'bvm','bamunka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1232,0,NULL,'bvn','buna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1233,0,NULL,'bvo','bolgo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1234,0,NULL,'bvq','birri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1235,0,NULL,'bvr','burarra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1236,0,NULL,'bvt','bati (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1237,0,NULL,'bvu','bukit malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(1238,0,NULL,'bvv','baniva','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1239,0,NULL,'bvw','boga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1240,0,NULL,'bvx','dibole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1241,0,NULL,'bvy','baybayanon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1242,0,NULL,'bvz','bauzi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1243,0,NULL,'bwa','bwatoo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1244,0,NULL,'bwb','namosi-naitasiri-serua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1245,0,NULL,'bwc','bwile','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1246,0,NULL,'bwd','bwaidoka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1247,0,NULL,'bwe','bwe karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1248,0,NULL,'bwf','boselewa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1249,0,NULL,'bwg','barwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1250,0,NULL,'bwh','bishuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1251,0,NULL,'bwi','baniwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1252,0,NULL,'bwj','láá láá bwamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1253,0,NULL,'bwk','bauwaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1254,0,NULL,'bwl','bwela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1255,0,NULL,'bwm','biwat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1256,0,NULL,'bwn','wunai bunu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1257,0,NULL,'bwo','borna (ethiopia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1257,0,NULL,'bwo','boro (ethiopia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1258,0,NULL,'bwp','mandobo bawah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1259,0,NULL,'bwq','southern bobo madaré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1260,0,NULL,'bwr','bura-pabir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1261,0,NULL,'bws','bomboma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1262,0,NULL,'bwt','bafaw-balong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1263,0,NULL,'bwu','buli (ghana)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1264,0,NULL,'bww','bwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1265,0,NULL,'bwx','bu-nao bunu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1266,0,NULL,'bwy','cwi bwamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1267,0,NULL,'bwz','bwisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1268,0,NULL,'bxa','bauro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1269,0,NULL,'bxb','belanda bor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1270,0,NULL,'bxc','molengue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1271,0,NULL,'bxd','pela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1272,0,NULL,'bxe','birale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1273,0,NULL,'bxf','bilur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1274,0,NULL,'bxg','bangala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1275,0,NULL,'bxh','buhutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1276,0,NULL,'bxi','pirlatapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1277,0,NULL,'bxj','bayungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1278,0,NULL,'bxk','bukusu','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(1278,0,NULL,'bxk','lubukusu','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(1279,0,NULL,'bxl','jalkunan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1280,0,NULL,'bxm','mongolia buriat','1248825600',NULL,NULL,NULL,NULL,'bua',NULL,NULL); +INSERT INTO "iana_records" VALUES(1281,0,NULL,'bxn','burduna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1282,0,NULL,'bxo','barikanchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1283,0,NULL,'bxp','bebil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1284,0,NULL,'bxq','beele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1285,0,NULL,'bxr','russia buriat','1248825600',NULL,NULL,NULL,NULL,'bua',NULL,NULL); +INSERT INTO "iana_records" VALUES(1286,0,NULL,'bxs','busam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1287,0,NULL,'bxu','china buriat','1248825600',NULL,NULL,NULL,NULL,'bua',NULL,NULL); +INSERT INTO "iana_records" VALUES(1288,0,NULL,'bxv','berakou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1289,0,NULL,'bxw','bankagooma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1290,0,NULL,'bxx','borna (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1291,0,NULL,'bxz','binahari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1292,0,NULL,'bya','batak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1293,0,NULL,'byb','bikya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1294,0,NULL,'byc','ubaghara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1295,0,NULL,'byd','benyadu''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1296,0,NULL,'bye','pouye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1297,0,NULL,'byf','bete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1298,0,NULL,'byg','baygo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1299,0,NULL,'byh','bhujel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1300,0,NULL,'byi','buyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1301,0,NULL,'byj','bina (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1302,0,NULL,'byk','biao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1303,0,NULL,'byl','bayono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1304,0,NULL,'bym','bidyara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1305,0,NULL,'byn','bilin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1305,0,NULL,'byn','blin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1306,0,NULL,'byo','biyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1307,0,NULL,'byp','bumaji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1308,0,NULL,'byq','basay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1309,0,NULL,'byr','baruya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1310,0,NULL,'bys','burak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1311,0,NULL,'byt','berti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1312,0,NULL,'byv','medumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1313,0,NULL,'byw','belhariya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1314,0,NULL,'byx','qaqet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1315,0,NULL,'byy','buya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1316,0,NULL,'byz','banaro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1317,0,NULL,'bza','bandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1318,0,NULL,'bzb','andio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1319,0,NULL,'bzd','bribri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1320,0,NULL,'bze','jenaama bozo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1321,0,NULL,'bzf','boikin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1322,0,NULL,'bzg','babuza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1323,0,NULL,'bzh','mapos buang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1324,0,NULL,'bzi','bisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1325,0,NULL,'bzj','belize kriol english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1326,0,NULL,'bzk','nicaragua creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1327,0,NULL,'bzl','boano (sulawesi)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1328,0,NULL,'bzm','bolondo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1329,0,NULL,'bzn','boano (maluku)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1330,0,NULL,'bzo','bozaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1331,0,NULL,'bzp','kemberano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1332,0,NULL,'bzq','buli (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1333,0,NULL,'bzr','biri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1334,0,NULL,'bzs','brazilian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1335,0,NULL,'bzt','brithenig','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1336,0,NULL,'bzu','burmeso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1337,0,NULL,'bzv','bebe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1338,0,NULL,'bzw','basa (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1339,0,NULL,'bzx','hainyaxo bozo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1340,0,NULL,'bzy','obanliku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1341,0,NULL,'bzz','evant','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1342,0,NULL,'caa','chortí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1343,0,NULL,'cab','garifuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1344,0,NULL,'cac','chuj','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1345,0,NULL,'cad','caddo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1346,0,NULL,'cae','laalaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1346,0,NULL,'cae','lehar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1347,0,NULL,'caf','southern carrier','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1348,0,NULL,'cag','nivaclé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1349,0,NULL,'cah','cahuarano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1350,0,NULL,'cai','central american indian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1351,0,NULL,'caj','chané','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1352,0,NULL,'cak','cakchiquel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1352,0,NULL,'cak','kaqchikel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1353,0,NULL,'cal','carolinian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1354,0,NULL,'cam','cemuhî','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1355,0,NULL,'can','chambri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1356,0,NULL,'cao','chácobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1357,0,NULL,'cap','chipaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1358,0,NULL,'caq','car nicobarese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1359,0,NULL,'car','galibi carib','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1360,0,NULL,'cas','tsimané','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1361,0,NULL,'cau','caucasian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1362,0,NULL,'cav','cavineña','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1363,0,NULL,'caw','callawalla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1364,0,NULL,'cax','chiquitano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1365,0,NULL,'cay','cayuga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1366,0,NULL,'caz','canichana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1367,0,NULL,'cba','chibchan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1368,0,NULL,'cbb','cabiyarí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1369,0,NULL,'cbc','carapana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1370,0,NULL,'cbd','carijona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1371,0,NULL,'cbe','chipiajes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1372,0,NULL,'cbg','chimila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1373,0,NULL,'cbh','cagua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1374,0,NULL,'cbi','chachi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1375,0,NULL,'cbj','ede cabe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1376,0,NULL,'cbk','chavacano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1377,0,NULL,'cbl','bualkhaw chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1378,0,NULL,'cbn','nyahkur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1379,0,NULL,'cbo','izora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1380,0,NULL,'cbr','cashibo-cacataibo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1381,0,NULL,'cbs','cashinahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1382,0,NULL,'cbt','chayahuita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1383,0,NULL,'cbu','candoshi-shapra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1384,0,NULL,'cbv','cacua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1385,0,NULL,'cbw','kinabalian','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1386,0,NULL,'cby','carabayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1387,0,NULL,'cca','cauca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1388,0,NULL,'ccc','chamicuro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1389,0,NULL,'ccd','cafundo creole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1390,0,NULL,'cce','chopi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1391,0,NULL,'ccg','samba daka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1392,0,NULL,'cch','atsam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1393,0,NULL,'ccj','kasanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1394,0,NULL,'ccl','cutchi-swahili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1395,0,NULL,'ccm','malaccan creole malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1396,0,NULL,'ccn','north caucasian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1397,0,NULL,'cco','comaltepec chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1398,0,NULL,'ccp','chakma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1399,0,NULL,'ccq','chaungtha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1400,0,NULL,'ccr','cacaopera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1401,0,NULL,'ccs','south caucasian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1402,0,NULL,'cda','choni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1403,0,NULL,'cdc','chadic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1404,0,NULL,'cdd','caddoan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1405,0,NULL,'cde','chenchu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1406,0,NULL,'cdf','chiru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1407,0,NULL,'cdg','chamari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1408,0,NULL,'cdh','chambeali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1409,0,NULL,'cdi','chodri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1410,0,NULL,'cdj','churahi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1411,0,NULL,'cdm','chepang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1412,0,NULL,'cdn','chaudangsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1413,0,NULL,'cdo','min dong chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1414,0,NULL,'cdr','cinda-regi-tiyal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1415,0,NULL,'cds','chadian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1416,0,NULL,'cdy','chadong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1417,0,NULL,'cdz','koda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1418,0,NULL,'cea','lower chehalis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1419,0,NULL,'ceb','cebuano','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1420,0,NULL,'ceg','chamacoco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1421,0,NULL,'cel','celtic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1422,0,NULL,'cen','cen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1423,0,NULL,'cet','centúúm','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1424,0,NULL,'cfa','dijim-bwilim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1425,0,NULL,'cfd','cara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1426,0,NULL,'cfg','como karim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1427,0,NULL,'cfm','falam chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1428,0,NULL,'cga','changriwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1429,0,NULL,'cgc','kagayanen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1430,0,NULL,'cgg','chiga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1431,0,NULL,'cgk','chocangacakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1432,0,NULL,'chb','chibcha','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1433,0,NULL,'chc','catawba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1434,0,NULL,'chd','highland oaxaca chontal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1435,0,NULL,'chf','tabasco chontal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1436,0,NULL,'chg','chagatai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1437,0,NULL,'chh','chinook','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1438,0,NULL,'chj','ojitlán chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1439,0,NULL,'chk','chuukese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1440,0,NULL,'chl','cahuilla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1441,0,NULL,'chm','mari (russia)','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1442,0,NULL,'chn','chinook jargon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1443,0,NULL,'cho','choctaw','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1444,0,NULL,'chp','chipewyan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1444,0,NULL,'chp','dene suline','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1445,0,NULL,'chq','quiotepec chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1446,0,NULL,'chr','cherokee','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1447,0,NULL,'cht','cholón','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1448,0,NULL,'chw','chuwabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1449,0,NULL,'chx','chantyal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1450,0,NULL,'chy','cheyenne','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1451,0,NULL,'chz','ozumacín chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1452,0,NULL,'cia','cia-cia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1453,0,NULL,'cib','ci gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1454,0,NULL,'cic','chickasaw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1455,0,NULL,'cid','chimariko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1456,0,NULL,'cie','cineni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1457,0,NULL,'cih','chinali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1458,0,NULL,'cik','chitkuli kinnauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1459,0,NULL,'cim','cimbrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1460,0,NULL,'cin','cinta larga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1461,0,NULL,'cip','chiapanec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1462,0,NULL,'cir','tiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1463,0,NULL,'ciw','chippewa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(1464,0,NULL,'ciy','chaima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1465,0,NULL,'cja','western cham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1466,0,NULL,'cje','chru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1467,0,NULL,'cjh','upper chehalis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1468,0,NULL,'cji','chamalal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1469,0,NULL,'cjk','chokwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1470,0,NULL,'cjm','eastern cham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1471,0,NULL,'cjn','chenapian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1472,0,NULL,'cjo','ashéninka pajonal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1473,0,NULL,'cjp','cabécar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1474,0,NULL,'cjr','chorotega','1248825600',1268265600,'mom',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1475,0,NULL,'cjs','shor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1476,0,NULL,'cjv','chuave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1477,0,NULL,'cjy','jinyu chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1478,0,NULL,'cka','khumi awa chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1479,0,NULL,'ckb','central kurdish','1248825600',NULL,NULL,NULL,NULL,'ku',NULL,NULL); +INSERT INTO "iana_records" VALUES(1480,0,NULL,'ckh','chak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1481,0,NULL,'ckl','cibak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1482,0,NULL,'cko','anufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1483,0,NULL,'ckq','kajakse','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1484,0,NULL,'ckr','kairak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1485,0,NULL,'cks','tayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1486,0,NULL,'ckt','chukot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1487,0,NULL,'cku','koasati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1488,0,NULL,'ckv','kavalan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1489,0,NULL,'ckx','caka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1490,0,NULL,'cky','cakfem-mushere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1491,0,NULL,'ckz','cakchiquel-quiché mixed language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1492,0,NULL,'cla','ron','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1493,0,NULL,'clc','chilcotin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1494,0,NULL,'cld','chaldean neo-aramaic','1248825600',NULL,NULL,NULL,NULL,'syr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1495,0,NULL,'cle','lealao chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1496,0,NULL,'clh','chilisso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1497,0,NULL,'cli','chakali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1498,0,NULL,'clk','idu-mishmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1499,0,NULL,'cll','chala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1500,0,NULL,'clm','clallam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1501,0,NULL,'clo','lowland oaxaca chontal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1502,0,NULL,'clu','caluyanun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1503,0,NULL,'clw','chulym','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1504,0,NULL,'cly','eastern highland chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1505,0,NULL,'cma','maa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1506,0,NULL,'cmc','chamic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1507,0,NULL,'cme','cerma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1508,0,NULL,'cmg','classical mongolian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1509,0,NULL,'cmi','emberá-chamí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1510,0,NULL,'cmk','chimakum','1248825600',1268265600,'xch',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1511,0,NULL,'cml','campalagian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1512,0,NULL,'cmm','michigamea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1513,0,NULL,'cmn','mandarin chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1514,0,NULL,'cmo','central mnong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1515,0,NULL,'cmr','mro chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1516,0,NULL,'cms','messapic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1517,0,NULL,'cmt','camtho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1518,0,NULL,'cna','changthang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1519,0,NULL,'cnb','chinbon chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1520,0,NULL,'cnc','côông','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1521,0,NULL,'cng','northern qiang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1522,0,NULL,'cnh','haka chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1523,0,NULL,'cni','asháninka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1524,0,NULL,'cnk','khumi chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1525,0,NULL,'cnl','lalana chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1526,0,NULL,'cno','con','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1527,0,NULL,'cns','central asmat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1528,0,NULL,'cnt','tepetotutla chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1529,0,NULL,'cnu','chenoua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1530,0,NULL,'cnw','ngawn chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1531,0,NULL,'cnx','middle cornish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1532,0,NULL,'coa','cocos islands malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(1533,0,NULL,'cob','chicomuceltec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1534,0,NULL,'coc','cocopa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1535,0,NULL,'cod','cocama-cocamilla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1536,0,NULL,'coe','koreguaje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1537,0,NULL,'cof','colorado','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1538,0,NULL,'cog','chong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1539,0,NULL,'coh','chichonyi-chidzihana-chikauma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1539,0,NULL,'coh','chonyi-dzihana-kauma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1540,0,NULL,'coj','cochimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1541,0,NULL,'cok','santa teresa cora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1542,0,NULL,'col','columbia-wenatchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1543,0,NULL,'com','comanche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1544,0,NULL,'con','cofán','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1545,0,NULL,'coo','comox','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1546,0,NULL,'cop','coptic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1547,0,NULL,'coq','coquille','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1548,0,NULL,'cot','caquinte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1549,0,NULL,'cou','wamey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1550,0,NULL,'cov','cao miao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1551,0,NULL,'cow','cowlitz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1552,0,NULL,'cox','nanti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1553,0,NULL,'coy','coyaima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1554,0,NULL,'coz','chochotec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1555,0,NULL,'cpa','palantla chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1556,0,NULL,'cpb','ucayali-yurúa ashéninka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1557,0,NULL,'cpc','ajyíninka apurucayali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1558,0,NULL,'cpe','english-based creoles and pidgins','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1559,0,NULL,'cpf','french-based creoles and pidgins','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1560,0,NULL,'cpg','cappadocian greek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1561,0,NULL,'cpi','chinese pidgin english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1562,0,NULL,'cpn','cherepon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1563,0,NULL,'cpp','portuguese-based creoles and pidgins','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1564,0,NULL,'cps','capiznon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1565,0,NULL,'cpu','pichis ashéninka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1566,0,NULL,'cpx','pu-xian chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1567,0,NULL,'cpy','south ucayali ashéninka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1568,0,NULL,'cqd','chuanqiandian cluster miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(1569,0,NULL,'cqu','chilean quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(1570,0,NULL,'cra','chara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1571,0,NULL,'crb','island carib','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1572,0,NULL,'crc','lonwolwol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1573,0,NULL,'crd','coeur d''alene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1574,0,NULL,'crf','caramanta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1575,0,NULL,'crg','michif','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1576,0,NULL,'crh','crimean tatar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1576,0,NULL,'crh','crimean turkish','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1577,0,NULL,'cri','sãotomense','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1578,0,NULL,'crj','southern east cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1579,0,NULL,'crk','plains cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1580,0,NULL,'crl','northern east cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1581,0,NULL,'crm','moose cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1582,0,NULL,'crn','el nayar cora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1583,0,NULL,'cro','crow','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1584,0,NULL,'crp','creoles and pidgins','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1585,0,NULL,'crq','iyo''wujwa chorote','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1586,0,NULL,'crr','carolina algonquian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1587,0,NULL,'crs','seselwa creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1588,0,NULL,'crt','iyojwa''ja chorote','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1589,0,NULL,'crv','chaura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1590,0,NULL,'crw','chrau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1591,0,NULL,'crx','carrier','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1592,0,NULL,'cry','cori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1593,0,NULL,'crz','cruzeño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1594,0,NULL,'csa','chiltepec chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1595,0,NULL,'csb','kashubian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1596,0,NULL,'csc','catalan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1596,0,NULL,'csc','lengua de señas catalana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1596,0,NULL,'csc','llengua de signes catalana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1597,0,NULL,'csd','chiangmai sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1598,0,NULL,'cse','czech sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1599,0,NULL,'csf','cuba sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1600,0,NULL,'csg','chilean sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1601,0,NULL,'csh','asho chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1602,0,NULL,'csi','coast miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1603,0,NULL,'csk','jola-kasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1604,0,NULL,'csl','chinese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1605,0,NULL,'csm','central sierra miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1606,0,NULL,'csn','colombian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1607,0,NULL,'cso','sochiapam chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1607,0,NULL,'cso','sochiapan chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1608,0,NULL,'csq','croatia sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1609,0,NULL,'csr','costa rican sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1610,0,NULL,'css','southern ohlone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1611,0,NULL,'cst','northern ohlone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1612,0,NULL,'csu','central sudanic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1613,0,NULL,'csw','swampy cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1614,0,NULL,'csy','siyin chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1615,0,NULL,'csz','coos','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1616,0,NULL,'cta','tataltepec chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1617,0,NULL,'ctc','chetco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1618,0,NULL,'ctd','tedim chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1619,0,NULL,'cte','tepinapa chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1620,0,NULL,'ctg','chittagonian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1621,0,NULL,'ctl','tlacoatzintepec chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1622,0,NULL,'ctm','chitimacha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1623,0,NULL,'ctn','chhintange','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1624,0,NULL,'cto','emberá-catío','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1625,0,NULL,'ctp','western highland chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1626,0,NULL,'cts','northern catanduanes bicolano','1248825600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(1627,0,NULL,'ctt','wayanad chetti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1628,0,NULL,'ctu','chol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1629,0,NULL,'ctz','zacatepec chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1630,0,NULL,'cua','cua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1631,0,NULL,'cub','cubeo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1632,0,NULL,'cuc','usila chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1633,0,NULL,'cug','cung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1634,0,NULL,'cuh','chuka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1634,0,NULL,'cuh','gichuka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1635,0,NULL,'cui','cuiba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1636,0,NULL,'cuj','mashco piro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1637,0,NULL,'cuk','san blas kuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1638,0,NULL,'cul','culina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1638,0,NULL,'cul','kulina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1639,0,NULL,'cum','cumeral','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1640,0,NULL,'cuo','cumanagoto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1641,0,NULL,'cup','cupeño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1642,0,NULL,'cuq','cun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1643,0,NULL,'cur','chhulung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1644,0,NULL,'cus','cushitic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1645,0,NULL,'cut','teutila cuicatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1646,0,NULL,'cuu','tai ya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1647,0,NULL,'cuv','cuvok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1648,0,NULL,'cuw','chukwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1649,0,NULL,'cux','tepeuxila cuicatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1650,0,NULL,'cvg','chug','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1651,0,NULL,'cvn','valle nacional chinantec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1652,0,NULL,'cwa','kabwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1653,0,NULL,'cwb','maindo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1654,0,NULL,'cwd','woods cree','1248825600',NULL,NULL,NULL,NULL,'cr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1655,0,NULL,'cwe','kwere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1656,0,NULL,'cwg','cheq wong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1656,0,NULL,'cwg','chewong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1657,0,NULL,'cwt','kuwaataay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1658,0,NULL,'cya','nopala chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1659,0,NULL,'cyb','cayubaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1660,0,NULL,'cyo','cuyonon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1661,0,NULL,'czh','huizhou chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1662,0,NULL,'czk','knaanic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1663,0,NULL,'czn','zenzontepec chatino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1664,0,NULL,'czo','min zhong chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(1665,0,NULL,'czt','zotung chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1666,0,NULL,'daa','dangaléat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1667,0,NULL,'dac','dambi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1668,0,NULL,'dad','marik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1669,0,NULL,'dae','duupa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1670,0,NULL,'daf','dan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1671,0,NULL,'dag','dagbani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1672,0,NULL,'dah','gwahatike','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1673,0,NULL,'dai','day','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1674,0,NULL,'daj','dar fur daju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1675,0,NULL,'dak','dakota','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1676,0,NULL,'dal','dahalo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1677,0,NULL,'dam','damakawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1678,0,NULL,'dao','daai chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1679,0,NULL,'dap','nisi (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1680,0,NULL,'daq','dandami maria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1681,0,NULL,'dar','dargwa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1682,0,NULL,'das','daho-doo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1683,0,NULL,'dau','dar sila daju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1684,0,NULL,'dav','dawida','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1684,0,NULL,'dav','taita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1685,0,NULL,'daw','davawenyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1686,0,NULL,'dax','dayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1687,0,NULL,'day','land dayak languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1688,0,NULL,'daz','dao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1689,0,NULL,'dba','bangi me','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1690,0,NULL,'dbb','deno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1691,0,NULL,'dbd','dadiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1692,0,NULL,'dbe','dabe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1693,0,NULL,'dbf','edopi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1694,0,NULL,'dbg','dogul dom dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1695,0,NULL,'dbi','doka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1696,0,NULL,'dbj','ida''an','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1697,0,NULL,'dbl','dyirbal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1698,0,NULL,'dbm','duguri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1699,0,NULL,'dbn','duriankere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1700,0,NULL,'dbo','dulbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1701,0,NULL,'dbp','duwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1702,0,NULL,'dbq','daba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1703,0,NULL,'dbr','dabarre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1704,0,NULL,'dbu','bondum dom dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1705,0,NULL,'dbv','dungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1706,0,NULL,'dby','dibiyaso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1707,0,NULL,'dcc','deccan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1708,0,NULL,'dcr','negerhollands','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1709,0,NULL,'ddd','dongotono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1710,0,NULL,'dde','doondo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1711,0,NULL,'ddg','fataluku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1712,0,NULL,'ddi','west goodenough','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1713,0,NULL,'ddj','jaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1714,0,NULL,'ddn','dendi (benin)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1715,0,NULL,'ddo','dido','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1716,0,NULL,'dds','donno so dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1717,0,NULL,'ddw','dawera-daweloor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1718,0,NULL,'dec','dagik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1719,0,NULL,'ded','dedua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1720,0,NULL,'dee','dewoin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1721,0,NULL,'def','dezfuli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1722,0,NULL,'deg','degema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1723,0,NULL,'deh','dehwari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1724,0,NULL,'dei','demisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1725,0,NULL,'dek','dek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1726,0,NULL,'del','delaware','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1727,0,NULL,'dem','dem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1728,0,NULL,'den','slave (athapascan)','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1729,0,NULL,'dep','pidgin delaware','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1730,0,NULL,'deq','dendi (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1731,0,NULL,'der','deori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1732,0,NULL,'des','desano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1733,0,NULL,'dev','domung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1734,0,NULL,'dez','dengese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1735,0,NULL,'dga','southern dagaare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1736,0,NULL,'dgb','bunoge dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1737,0,NULL,'dgc','casiguran dumagat agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1738,0,NULL,'dgd','dagaari dioula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1739,0,NULL,'dge','degenan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1740,0,NULL,'dgg','doga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1741,0,NULL,'dgh','dghwede','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1742,0,NULL,'dgi','northern dagara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1743,0,NULL,'dgk','dagba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1744,0,NULL,'dgn','dagoman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1745,0,NULL,'dgo','dogri (individual language)','1248825600',NULL,NULL,NULL,NULL,'doi',NULL,NULL); +INSERT INTO "iana_records" VALUES(1746,0,NULL,'dgr','dogrib','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1747,0,NULL,'dgs','dogoso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1748,0,NULL,'dgu','degaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1749,0,NULL,'dgx','doghoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1750,0,NULL,'dgz','daga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1751,0,NULL,'dha','dhanwar (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1752,0,NULL,'dhd','dhundari','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(1753,0,NULL,'dhg','dhangu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1754,0,NULL,'dhi','dhimal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1755,0,NULL,'dhl','dhalandji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1756,0,NULL,'dhm','zemba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1757,0,NULL,'dhn','dhanki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1758,0,NULL,'dho','dhodia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1759,0,NULL,'dhr','dhargari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1760,0,NULL,'dhs','dhaiso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1761,0,NULL,'dhu','dhurga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1762,0,NULL,'dhv','dehu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1763,0,NULL,'dhw','dhanwar (nepal)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1764,0,NULL,'dia','dia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1765,0,NULL,'dib','south central dinka','1248825600',NULL,NULL,NULL,NULL,'din',NULL,NULL); +INSERT INTO "iana_records" VALUES(1766,0,NULL,'dic','lakota dida','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1767,0,NULL,'did','didinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1768,0,NULL,'dif','dieri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1769,0,NULL,'dig','chidigo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1769,0,NULL,'dig','digo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1770,0,NULL,'dih','kumiai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1771,0,NULL,'dii','dimbong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1772,0,NULL,'dij','dai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1773,0,NULL,'dik','southwestern dinka','1248825600',NULL,NULL,NULL,NULL,'din',NULL,NULL); +INSERT INTO "iana_records" VALUES(1774,0,NULL,'dil','dilling','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1775,0,NULL,'dim','dime','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1776,0,NULL,'din','dinka','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1777,0,NULL,'dio','dibo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1778,0,NULL,'dip','northeastern dinka','1248825600',NULL,NULL,NULL,NULL,'din',NULL,NULL); +INSERT INTO "iana_records" VALUES(1779,0,NULL,'diq','dimli (individual language)','1248825600',NULL,NULL,NULL,NULL,'zza',NULL,NULL); +INSERT INTO "iana_records" VALUES(1780,0,NULL,'dir','dirim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1781,0,NULL,'dis','dimasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1782,0,NULL,'dit','dirari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1783,0,NULL,'diu','diriku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1784,0,NULL,'diw','northwestern dinka','1248825600',NULL,NULL,NULL,NULL,'din',NULL,NULL); +INSERT INTO "iana_records" VALUES(1785,0,NULL,'dix','dixon reef','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1786,0,NULL,'diy','diuwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1787,0,NULL,'diz','ding','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1788,0,NULL,'djb','djinba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1789,0,NULL,'djc','dar daju daju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1790,0,NULL,'djd','djamindjung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1791,0,NULL,'dje','zarma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1792,0,NULL,'djf','djangun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1793,0,NULL,'dji','djinang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1794,0,NULL,'djj','djeebbana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1795,0,NULL,'djk','businenge tongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1795,0,NULL,'djk','eastern maroon creole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1795,0,NULL,'djk','nenge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1796,0,NULL,'djl','djiwarli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1797,0,NULL,'djm','jamsay dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1798,0,NULL,'djn','djauan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1799,0,NULL,'djo','jangkang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1800,0,NULL,'djr','djambarrpuyngu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1801,0,NULL,'dju','kapriman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1802,0,NULL,'djw','djawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1803,0,NULL,'dka','dakpakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1804,0,NULL,'dkk','dakka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1805,0,NULL,'dkl','kolum so dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1806,0,NULL,'dkr','kuijau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1807,0,NULL,'dks','southeastern dinka','1248825600',NULL,NULL,NULL,NULL,'din',NULL,NULL); +INSERT INTO "iana_records" VALUES(1808,0,NULL,'dkx','mazagway','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1809,0,NULL,'dlg','dolgan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1810,0,NULL,'dlm','dalmatian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1811,0,NULL,'dln','darlong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1812,0,NULL,'dma','duma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1813,0,NULL,'dmc','dimir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1814,0,NULL,'dme','dugwor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1815,0,NULL,'dmg','upper kinabatangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1816,0,NULL,'dmk','domaaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1817,0,NULL,'dml','dameli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1818,0,NULL,'dmm','dama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1819,0,NULL,'dmn','mande languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1820,0,NULL,'dmo','kemezung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1821,0,NULL,'dmr','east damar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1822,0,NULL,'dms','dampelas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1823,0,NULL,'dmu','dubu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1823,0,NULL,'dmu','tebi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1824,0,NULL,'dmv','dumpas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1825,0,NULL,'dmx','dema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1826,0,NULL,'dmy','demta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1826,0,NULL,'dmy','sowari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1827,0,NULL,'dna','upper grand valley dani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1828,0,NULL,'dnd','daonda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1829,0,NULL,'dne','ndendeule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1830,0,NULL,'dng','dungan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1831,0,NULL,'dni','lower grand valley dani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1832,0,NULL,'dnk','dengka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1833,0,NULL,'dnn','dzùùngoo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1834,0,NULL,'dnr','danaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1835,0,NULL,'dnt','mid grand valley dani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1836,0,NULL,'dnu','danau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1837,0,NULL,'dnw','western dani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1838,0,NULL,'dny','dení','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1839,0,NULL,'doa','dom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1840,0,NULL,'dob','dobu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1841,0,NULL,'doc','northern dong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1842,0,NULL,'doe','doe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1843,0,NULL,'dof','domu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1844,0,NULL,'doh','dong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1845,0,NULL,'doi','dogri (macrolanguage)','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(1846,0,NULL,'dok','dondo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1847,0,NULL,'dol','doso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1848,0,NULL,'don','toura (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1849,0,NULL,'doo','dongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1850,0,NULL,'dop','lukpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1851,0,NULL,'doq','dominican sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1852,0,NULL,'dor','dori''o','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1853,0,NULL,'dos','dogosé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1854,0,NULL,'dot','dass','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1855,0,NULL,'dov','dombe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1856,0,NULL,'dow','doyayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1857,0,NULL,'dox','bussa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1858,0,NULL,'doy','dompo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1859,0,NULL,'doz','dorze','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1860,0,NULL,'dpp','papar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1861,0,NULL,'dra','dravidian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1862,0,NULL,'drb','dair','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1863,0,NULL,'drd','darmiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1864,0,NULL,'dre','dolpo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1865,0,NULL,'drg','rungus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1866,0,NULL,'drh','darkhat','1248825600',1268265600,'khk',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1867,0,NULL,'dri','c''lela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1868,0,NULL,'drl','darling','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1869,0,NULL,'drn','west damar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1870,0,NULL,'dro','daro-matu melanau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1871,0,NULL,'drq','dura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1872,0,NULL,'drr','dororo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1873,0,NULL,'drs','gedeo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1874,0,NULL,'drt','drents','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1875,0,NULL,'dru','rukai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1876,0,NULL,'drw','darwazi','1248825600',1268265600,'prs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1877,0,NULL,'dry','darai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1878,0,NULL,'dsb','lower sorbian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1879,0,NULL,'dse','dutch sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1880,0,NULL,'dsh','daasanach','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1881,0,NULL,'dsi','disa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1882,0,NULL,'dsl','danish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1883,0,NULL,'dsn','dusner','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1884,0,NULL,'dso','desiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1885,0,NULL,'dsq','tadaksahak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1886,0,NULL,'dta','daur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1887,0,NULL,'dtb','labuk-kinabatangan kadazan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1888,0,NULL,'dti','ana tinga dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1889,0,NULL,'dtk','tene kan dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1890,0,NULL,'dtm','tomo kan dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1891,0,NULL,'dtp','central dusun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1892,0,NULL,'dtr','lotud','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1893,0,NULL,'dts','toro so dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1894,0,NULL,'dtt','toro tegu dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1895,0,NULL,'dtu','tebul ure dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1896,0,NULL,'dua','duala','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1897,0,NULL,'dub','dubli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1898,0,NULL,'duc','duna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1899,0,NULL,'dud','hun-saare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1900,0,NULL,'due','umiray dumaget agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1901,0,NULL,'duf','dumbea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1902,0,NULL,'dug','chiduruma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1902,0,NULL,'dug','duruma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1903,0,NULL,'duh','dungra bhil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1904,0,NULL,'dui','dumun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1905,0,NULL,'duj','dhuwal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1906,0,NULL,'duk','duduela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1907,0,NULL,'dul','alabat island agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1908,0,NULL,'dum','middle dutch (ca. 1050-1350)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1909,0,NULL,'dun','dusun deyah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1910,0,NULL,'duo','dupaninan agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1911,0,NULL,'dup','duano','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(1912,0,NULL,'duq','dusun malang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1913,0,NULL,'dur','dii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1914,0,NULL,'dus','dumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1915,0,NULL,'duu','drung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1916,0,NULL,'duv','duvle','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1917,0,NULL,'duw','dusun witu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1918,0,NULL,'dux','duungooma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1919,0,NULL,'duy','dicamay agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1920,0,NULL,'duz','duli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1921,0,NULL,'dva','duau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1922,0,NULL,'dwa','diri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1923,0,NULL,'dwl','walo kumbe dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1924,0,NULL,'dwr','dawro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1925,0,NULL,'dws','dutton world speedwords','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1926,0,NULL,'dww','dawawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1927,0,NULL,'dya','dyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1928,0,NULL,'dyb','dyaberdyaber','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1929,0,NULL,'dyd','dyugun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1930,0,NULL,'dyg','villa viciosa agta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1931,0,NULL,'dyi','djimini senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1932,0,NULL,'dym','yanda dom dogon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1933,0,NULL,'dyn','dyangadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1934,0,NULL,'dyo','jola-fonyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1935,0,NULL,'dyu','dyula','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1936,0,NULL,'dyy','dyaabugay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1937,0,NULL,'dza','tunzu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1938,0,NULL,'dzd','daza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1939,0,NULL,'dzg','dazaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1940,0,NULL,'dzl','dzalakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1941,0,NULL,'dzn','dzando','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1942,0,NULL,'ebg','ebughu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1943,0,NULL,'ebk','eastern bontok','1268265600',NULL,NULL,NULL,NULL,'bnc',NULL,NULL); +INSERT INTO "iana_records" VALUES(1944,0,NULL,'ebo','teke-ebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1945,0,NULL,'ebr','ebrié','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1946,0,NULL,'ebu','embu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1946,0,NULL,'ebu','kiembu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1947,0,NULL,'ecr','eteocretan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1948,0,NULL,'ecs','ecuadorian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1949,0,NULL,'ecy','eteocypriot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1950,0,NULL,'eee','e','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1951,0,NULL,'efa','efai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1952,0,NULL,'efe','efe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1953,0,NULL,'efi','efik','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1954,0,NULL,'ega','ega','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1955,0,NULL,'egl','emilian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1956,0,NULL,'ego','eggon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1957,0,NULL,'egx','egyptian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(1958,0,NULL,'egy','egyptian (ancient)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1959,0,NULL,'ehu','ehueun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1960,0,NULL,'eip','eipomek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1961,0,NULL,'eit','eitiep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1962,0,NULL,'eiv','askopan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1963,0,NULL,'eja','ejamat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1964,0,NULL,'eka','ekajuk','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1965,0,NULL,'eke','ekit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1966,0,NULL,'ekg','ekari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1967,0,NULL,'eki','eki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1968,0,NULL,'ekk','standard estonian','1248825600',NULL,NULL,NULL,NULL,'et',NULL,NULL); +INSERT INTO "iana_records" VALUES(1969,0,NULL,'ekl','kol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1970,0,NULL,'ekm','elip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1971,0,NULL,'eko','koti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1972,0,NULL,'ekp','ekpeye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1973,0,NULL,'ekr','yace','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1974,0,NULL,'eky','eastern kayah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1975,0,NULL,'ele','elepi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1976,0,NULL,'elh','el hugeirat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1977,0,NULL,'eli','nding','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1978,0,NULL,'elk','elkei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1979,0,NULL,'elm','eleme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1980,0,NULL,'elo','el molo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1981,0,NULL,'elp','elpaputih','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1982,0,NULL,'elu','elu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1983,0,NULL,'elx','elamite','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1984,0,NULL,'ema','emai-iuleha-ora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1985,0,NULL,'emb','embaloh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1986,0,NULL,'eme','emerillon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1987,0,NULL,'emg','eastern meohang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1988,0,NULL,'emi','mussau-emira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1989,0,NULL,'emk','eastern maninkakan','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(1990,0,NULL,'emm','mamulique','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1991,0,NULL,'emn','eman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1992,0,NULL,'emo','emok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1993,0,NULL,'emp','northern emberá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1994,0,NULL,'ems','pacific gulf yupik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1995,0,NULL,'emu','eastern muria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1996,0,NULL,'emw','emplawas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1997,0,NULL,'emx','erromintxela','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1998,0,NULL,'emy','epigraphic mayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(1999,0,NULL,'ena','apali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2000,0,NULL,'enb','markweeta','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(2001,0,NULL,'enc','en','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2002,0,NULL,'end','ende','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2003,0,NULL,'enf','forest enets','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2004,0,NULL,'enh','tundra enets','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2005,0,NULL,'enm','middle english (1100-1500)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2006,0,NULL,'enn','engenni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2007,0,NULL,'eno','enggano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2008,0,NULL,'enq','enga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2009,0,NULL,'enr','emem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2009,0,NULL,'enr','emumu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2010,0,NULL,'enu','enu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2011,0,NULL,'env','enwan (edu state)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2012,0,NULL,'enw','enwan (akwa ibom state)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2013,0,NULL,'eot','beti (côte d''ivoire)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2014,0,NULL,'epi','epie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2015,0,NULL,'era','eravallan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2016,0,NULL,'erg','sie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2017,0,NULL,'erh','eruwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2018,0,NULL,'eri','ogea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2019,0,NULL,'erk','south efate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2020,0,NULL,'ero','horpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2021,0,NULL,'err','erre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2022,0,NULL,'ers','ersu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2023,0,NULL,'ert','eritai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2024,0,NULL,'erw','erokwanas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2025,0,NULL,'ese','ese ejja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2026,0,NULL,'esh','eshtehardi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2027,0,NULL,'esi','north alaskan inupiatun','1248825600',NULL,NULL,NULL,NULL,'ik',NULL,NULL); +INSERT INTO "iana_records" VALUES(2028,0,NULL,'esk','northwest alaska inupiatun','1248825600',NULL,NULL,NULL,NULL,'ik',NULL,NULL); +INSERT INTO "iana_records" VALUES(2029,0,NULL,'esl','egypt sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2030,0,NULL,'esm','esuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2031,0,NULL,'esn','salvadoran sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2032,0,NULL,'eso','estonian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2033,0,NULL,'esq','esselen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2034,0,NULL,'ess','central siberian yupik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2035,0,NULL,'esu','central yupik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2036,0,NULL,'esx','eskimo-aleut languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2037,0,NULL,'etb','etebi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2038,0,NULL,'etc','etchemin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2039,0,NULL,'eth','ethiopian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2040,0,NULL,'etn','eton (vanuatu)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2041,0,NULL,'eto','eton (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2042,0,NULL,'etr','edolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2043,0,NULL,'ets','yekhee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2044,0,NULL,'ett','etruscan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2045,0,NULL,'etu','ejagham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2046,0,NULL,'etx','eten','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2047,0,NULL,'etz','semimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2048,0,NULL,'euq','basque (family)','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2049,0,NULL,'eve','even','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2050,0,NULL,'evh','uvbie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2051,0,NULL,'evn','evenki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2052,0,NULL,'ewo','ewondo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2053,0,NULL,'ext','extremaduran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2054,0,NULL,'eya','eyak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2055,0,NULL,'eyo','keiyo','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(2056,0,NULL,'eze','uzekwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2057,0,NULL,'faa','fasu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2058,0,NULL,'fab','fa d''ambu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2059,0,NULL,'fad','wagi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2060,0,NULL,'faf','fagani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2061,0,NULL,'fag','finongan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2062,0,NULL,'fah','baissa fali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2063,0,NULL,'fai','faiwol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2064,0,NULL,'faj','faita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2065,0,NULL,'fak','fang (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2066,0,NULL,'fal','south fali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2067,0,NULL,'fam','fam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2068,0,NULL,'fan','fang (equatorial guinea)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2069,0,NULL,'fap','palor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2070,0,NULL,'far','fataleka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2071,0,NULL,'fat','fanti','1129420800',NULL,NULL,NULL,NULL,'ak',NULL,NULL); +INSERT INTO "iana_records" VALUES(2072,0,NULL,'fau','fayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2073,0,NULL,'fax','fala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2074,0,NULL,'fay','southwestern fars','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2075,0,NULL,'faz','northwestern fars','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2076,0,NULL,'fbl','west albay bikol','1268265600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(2077,0,NULL,'fcs','quebec sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2078,0,NULL,'fer','feroge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2079,0,NULL,'ffi','foia foia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2080,0,NULL,'ffm','maasina fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2081,0,NULL,'fgr','fongoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2082,0,NULL,'fia','nobiin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2083,0,NULL,'fie','fyer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2084,0,NULL,'fil','filipino','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2084,0,NULL,'fil','pilipino','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2085,0,NULL,'fip','fipa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2086,0,NULL,'fir','firan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2087,0,NULL,'fit','tornedalen finnish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2088,0,NULL,'fiu','finno-ugrian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2089,0,NULL,'fiw','fiwaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2090,0,NULL,'fkv','kven finnish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2091,0,NULL,'fla','kalispel-pend d''oreille','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2092,0,NULL,'flh','foau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2093,0,NULL,'fli','fali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2094,0,NULL,'fll','north fali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2095,0,NULL,'fln','flinders island','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2096,0,NULL,'flr','fuliiru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2097,0,NULL,'fly','tsotsitaal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2098,0,NULL,'fmp','fe''fe''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2099,0,NULL,'fmu','far western muria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2100,0,NULL,'fng','fanagalo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2101,0,NULL,'fni','fania','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2102,0,NULL,'fod','foodo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2103,0,NULL,'foi','foi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2104,0,NULL,'fom','foma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2105,0,NULL,'fon','fon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2106,0,NULL,'for','fore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2107,0,NULL,'fos','siraya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2108,0,NULL,'fox','formosan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2109,0,NULL,'fpe','fernando po creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2110,0,NULL,'fqs','fas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2111,0,NULL,'frc','cajun french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2112,0,NULL,'frd','fordata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2113,0,NULL,'frk','frankish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2114,0,NULL,'frm','middle french (ca. 1400-1600)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2115,0,NULL,'fro','old french (842-ca. 1400)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2116,0,NULL,'frp','arpitan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2116,0,NULL,'frp','francoprovençal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2117,0,NULL,'frq','forak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2118,0,NULL,'frr','northern frisian','1141776000',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2119,0,NULL,'frs','eastern frisian','1141776000',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2120,0,NULL,'frt','fortsenal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2121,0,NULL,'fse','finnish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2122,0,NULL,'fsl','french sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2123,0,NULL,'fss','finland-swedish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2123,0,NULL,'fss','finlandssvenskt teckenspråk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2123,0,NULL,'fss','suomenruotsalainen viittomakieli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2124,0,NULL,'fub','adamawa fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2125,0,NULL,'fuc','pulaar','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2126,0,NULL,'fud','east futuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2127,0,NULL,'fue','borgu fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2128,0,NULL,'fuf','pular','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2129,0,NULL,'fuh','western niger fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2130,0,NULL,'fui','bagirmi fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2131,0,NULL,'fuj','ko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2132,0,NULL,'fum','fum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2133,0,NULL,'fun','fulniô','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2134,0,NULL,'fuq','central-eastern niger fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2135,0,NULL,'fur','friulian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2136,0,NULL,'fut','futuna-aniwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2137,0,NULL,'fuu','furu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2138,0,NULL,'fuv','nigerian fulfulde','1248825600',NULL,NULL,NULL,NULL,'ff',NULL,NULL); +INSERT INTO "iana_records" VALUES(2139,0,NULL,'fuy','fuyug','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2140,0,NULL,'fvr','fur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2141,0,NULL,'fwa','fwâi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2142,0,NULL,'fwe','fwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2143,0,NULL,'gaa','ga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2144,0,NULL,'gab','gabri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2145,0,NULL,'gac','mixed great andamanese','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2146,0,NULL,'gad','gaddang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2147,0,NULL,'gae','guarequena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2148,0,NULL,'gaf','gende','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2149,0,NULL,'gag','gagauz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2150,0,NULL,'gah','alekano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2151,0,NULL,'gai','borei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2152,0,NULL,'gaj','gadsup','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2153,0,NULL,'gak','gamkonora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2154,0,NULL,'gal','galoli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2155,0,NULL,'gam','kandawo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2156,0,NULL,'gan','gan chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(2157,0,NULL,'gao','gants','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2158,0,NULL,'gap','gal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2159,0,NULL,'gaq','gata''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2160,0,NULL,'gar','galeya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2161,0,NULL,'gas','adiwasi garasia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2162,0,NULL,'gat','kenati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2163,0,NULL,'gau','mudhili gadaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2164,0,NULL,'gav','gabutamon','1248825600',1268265600,'dev',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2165,0,NULL,'gaw','nobonob','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2166,0,NULL,'gax','borana-arsi-guji oromo','1248825600',NULL,NULL,NULL,NULL,'om',NULL,NULL); +INSERT INTO "iana_records" VALUES(2167,0,NULL,'gay','gayo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2168,0,NULL,'gaz','west central oromo','1248825600',NULL,NULL,NULL,NULL,'om',NULL,NULL); +INSERT INTO "iana_records" VALUES(2169,0,NULL,'gba','gbaya (central african republic)','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2170,0,NULL,'gbb','kaytetye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2171,0,NULL,'gbc','garawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2172,0,NULL,'gbd','karadjeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2173,0,NULL,'gbe','niksek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2174,0,NULL,'gbf','gaikundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2175,0,NULL,'gbg','gbanziri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2176,0,NULL,'gbh','defi gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2177,0,NULL,'gbi','galela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2178,0,NULL,'gbj','bodo gadaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2179,0,NULL,'gbk','gaddi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2180,0,NULL,'gbl','gamit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2181,0,NULL,'gbm','garhwali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2182,0,NULL,'gbn','mo''da','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2183,0,NULL,'gbo','northern grebo','1248825600',NULL,NULL,NULL,NULL,'grb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2184,0,NULL,'gbp','gbaya-bossangoa','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(2185,0,NULL,'gbq','gbaya-bozoum','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(2186,0,NULL,'gbr','gbagyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2187,0,NULL,'gbs','gbesi gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2188,0,NULL,'gbu','gagadu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2189,0,NULL,'gbv','gbanu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2190,0,NULL,'gbx','eastern xwla gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2191,0,NULL,'gby','gbari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2192,0,NULL,'gbz','zoroastrian dari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2193,0,NULL,'gcc','mali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2194,0,NULL,'gcd','ganggalida','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2195,0,NULL,'gce','galice','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2196,0,NULL,'gcf','guadeloupean creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2197,0,NULL,'gcl','grenadian creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2198,0,NULL,'gcn','gaina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2199,0,NULL,'gcr','guianese creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2200,0,NULL,'gct','colonia tovar german','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2201,0,NULL,'gda','gade lohar','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(2202,0,NULL,'gdb','pottangi ollar gadaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2203,0,NULL,'gdc','gugu badhun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2204,0,NULL,'gdd','gedaged','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2205,0,NULL,'gde','gude','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2206,0,NULL,'gdf','guduf-gava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2207,0,NULL,'gdg','ga''dang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2208,0,NULL,'gdh','gadjerawang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2209,0,NULL,'gdi','gundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2210,0,NULL,'gdj','gurdjar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2211,0,NULL,'gdk','gadang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2212,0,NULL,'gdl','dirasha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2213,0,NULL,'gdm','laal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2214,0,NULL,'gdn','umanakaina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2215,0,NULL,'gdo','ghodoberi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2216,0,NULL,'gdq','mehri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2217,0,NULL,'gdr','wipi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2218,0,NULL,'gdu','gudu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2219,0,NULL,'gdx','godwari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2220,0,NULL,'gea','geruma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2221,0,NULL,'geb','kire','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2222,0,NULL,'gec','gboloo grebo','1248825600',NULL,NULL,NULL,NULL,'grb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2223,0,NULL,'ged','gade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2224,0,NULL,'geg','gengle','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2225,0,NULL,'geh','hutterisch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2225,0,NULL,'geh','hutterite german','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2226,0,NULL,'gei','gebe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2227,0,NULL,'gej','gen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2228,0,NULL,'gek','yiwom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2229,0,NULL,'gel','kag-fer-jiir-koor-ror-us-zuksun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2230,0,NULL,'gem','germanic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2231,0,NULL,'geq','geme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2232,0,NULL,'ges','geser-gorom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2233,0,NULL,'gew','gera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2234,0,NULL,'gex','garre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2235,0,NULL,'gey','enya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2236,0,NULL,'gez','geez','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2237,0,NULL,'gfk','patpatar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2238,0,NULL,'gft','gafat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2239,0,NULL,'gga','gao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2240,0,NULL,'ggb','gbii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2241,0,NULL,'ggd','gugadj','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2242,0,NULL,'gge','guragone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2243,0,NULL,'ggg','gurgula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2244,0,NULL,'ggk','kungarakany','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2245,0,NULL,'ggl','ganglau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2246,0,NULL,'ggn','eastern gurung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2247,0,NULL,'ggo','southern gondi','1248825600',NULL,NULL,NULL,NULL,'gon',NULL,NULL); +INSERT INTO "iana_records" VALUES(2248,0,NULL,'ggr','aghu tharnggalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2249,0,NULL,'ggt','gitua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2250,0,NULL,'ggu','gagu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2251,0,NULL,'ggw','gogodala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2252,0,NULL,'gha','ghadamès','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2253,0,NULL,'ghc','hiberno-scottish gaelic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2254,0,NULL,'ghe','southern ghale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2255,0,NULL,'ghh','northern ghale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2256,0,NULL,'ghk','geko karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2257,0,NULL,'ghl','ghulfan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2258,0,NULL,'ghn','ghanongga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2259,0,NULL,'gho','ghomara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2260,0,NULL,'ghr','ghera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2261,0,NULL,'ghs','guhu-samane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2262,0,NULL,'ght','kutang ghale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2263,0,NULL,'gia','kitja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2264,0,NULL,'gib','gibanawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2265,0,NULL,'gic','gail','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2266,0,NULL,'gid','gidar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2267,0,NULL,'gig','goaria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2268,0,NULL,'gil','gilbertese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2269,0,NULL,'gim','gimi (eastern highlands)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2270,0,NULL,'gin','hinukh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2271,0,NULL,'gio','gelao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2272,0,NULL,'gip','gimi (west new britain)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2273,0,NULL,'giq','green gelao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2274,0,NULL,'gir','red gelao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2275,0,NULL,'gis','north giziga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2276,0,NULL,'git','gitxsan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2277,0,NULL,'giw','white gelao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2278,0,NULL,'gix','gilima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2279,0,NULL,'giy','giyug','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2280,0,NULL,'giz','south giziga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2281,0,NULL,'gji','geji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2282,0,NULL,'gjk','kachi koli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2283,0,NULL,'gjn','gonja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2284,0,NULL,'gju','gujari','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(2285,0,NULL,'gka','guya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2286,0,NULL,'gke','ndai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2287,0,NULL,'gkn','gokana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2288,0,NULL,'gkp','guinea kpelle','1248825600',NULL,NULL,NULL,NULL,'kpe',NULL,NULL); +INSERT INTO "iana_records" VALUES(2289,0,NULL,'glc','bon gula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2290,0,NULL,'gld','nanai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2291,0,NULL,'glh','northwest pashayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2292,0,NULL,'gli','guliguli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2293,0,NULL,'glj','gula iro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2294,0,NULL,'glk','gilaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2295,0,NULL,'glo','galambu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2296,0,NULL,'glr','glaro-twabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2297,0,NULL,'glu','gula (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2298,0,NULL,'glw','glavda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2299,0,NULL,'gly','gule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2300,0,NULL,'gma','gambera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2301,0,NULL,'gmb','gula''alaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2302,0,NULL,'gmd','mághdì','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2303,0,NULL,'gme','east germanic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2304,0,NULL,'gmh','middle high german (ca. 1050-1500)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2305,0,NULL,'gml','middle low german','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2306,0,NULL,'gmm','gbaya-mbodomo','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(2307,0,NULL,'gmn','gimnime','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2308,0,NULL,'gmq','north germanic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2309,0,NULL,'gmu','gumalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2310,0,NULL,'gmv','gamo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2311,0,NULL,'gmw','west germanic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2312,0,NULL,'gmx','magoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2313,0,NULL,'gmy','mycenaean greek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2314,0,NULL,'gna','kaansa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2315,0,NULL,'gnb','gangte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2316,0,NULL,'gnc','guanche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2317,0,NULL,'gnd','zulgo-gemzek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2318,0,NULL,'gne','ganang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2319,0,NULL,'gng','ngangam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2320,0,NULL,'gnh','lere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2321,0,NULL,'gni','gooniyandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2322,0,NULL,'gnk','//gana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2323,0,NULL,'gnl','gangulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2324,0,NULL,'gnm','ginuman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2325,0,NULL,'gnn','gumatj','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2326,0,NULL,'gno','northern gondi','1248825600',NULL,NULL,NULL,NULL,'gon',NULL,NULL); +INSERT INTO "iana_records" VALUES(2327,0,NULL,'gnq','gana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2328,0,NULL,'gnr','gureng gureng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2329,0,NULL,'gnt','guntai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2330,0,NULL,'gnu','gnau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2331,0,NULL,'gnw','western bolivian guaraní','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2332,0,NULL,'gnz','ganzi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2333,0,NULL,'goa','guro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2334,0,NULL,'gob','playero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2335,0,NULL,'goc','gorakor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2336,0,NULL,'god','godié','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2337,0,NULL,'goe','gongduk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2338,0,NULL,'gof','gofa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2339,0,NULL,'gog','gogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2340,0,NULL,'goh','old high german (ca. 750-1050)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2341,0,NULL,'goi','gobasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2342,0,NULL,'goj','gowlan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2343,0,NULL,'gok','gowli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2344,0,NULL,'gol','gola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2345,0,NULL,'gom','goan konkani','1248825600',NULL,NULL,NULL,NULL,'kok',NULL,NULL); +INSERT INTO "iana_records" VALUES(2346,0,NULL,'gon','gondi','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2347,0,NULL,'goo','gone dau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2348,0,NULL,'gop','yeretuar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2349,0,NULL,'goq','gorap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2350,0,NULL,'gor','gorontalo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2351,0,NULL,'gos','gronings','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2352,0,NULL,'got','gothic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2353,0,NULL,'gou','gavar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2354,0,NULL,'gow','gorowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2355,0,NULL,'gox','gobu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2356,0,NULL,'goy','goundo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2357,0,NULL,'goz','gozarkhani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2358,0,NULL,'gpa','gupa-abawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2359,0,NULL,'gpn','taiap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2360,0,NULL,'gqa','ga''anda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2361,0,NULL,'gqi','guiqiong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2362,0,NULL,'gqn','guana (brazil)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2363,0,NULL,'gqr','gor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2364,0,NULL,'gra','rajput garasia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2365,0,NULL,'grb','grebo','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2366,0,NULL,'grc','ancient greek (to 1453)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2367,0,NULL,'grd','guruntum-mbaaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2368,0,NULL,'grg','madi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2369,0,NULL,'grh','gbiri-niragu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2370,0,NULL,'gri','ghari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2371,0,NULL,'grj','southern grebo','1248825600',NULL,NULL,NULL,NULL,'grb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2372,0,NULL,'grk','greek languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2373,0,NULL,'grm','kota marudu talantang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2374,0,NULL,'gro','groma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2375,0,NULL,'grq','gorovu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2376,0,NULL,'grr','taznatit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2377,0,NULL,'grs','gresi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2378,0,NULL,'grt','garo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2379,0,NULL,'gru','kistane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2380,0,NULL,'grv','central grebo','1248825600',NULL,NULL,NULL,NULL,'grb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2381,0,NULL,'grw','gweda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2382,0,NULL,'grx','guriaso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2383,0,NULL,'gry','barclayville grebo','1248825600',NULL,NULL,NULL,NULL,'grb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2384,0,NULL,'grz','guramalum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2385,0,NULL,'gse','ghanaian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2386,0,NULL,'gsg','german sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2387,0,NULL,'gsl','gusilay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2388,0,NULL,'gsm','guatemalan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2389,0,NULL,'gsn','gusan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2390,0,NULL,'gso','southwest gbaya','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(2391,0,NULL,'gsp','wasembo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2392,0,NULL,'gss','greek sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2393,0,NULL,'gsw','alemannic','1141776000',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2393,0,NULL,'gsw','alsatian','1141776000',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2393,0,NULL,'gsw','swiss german','1141776000',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2394,0,NULL,'gta','guató','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2395,0,NULL,'gti','gbati-ri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2396,0,NULL,'gua','shiki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2397,0,NULL,'gub','guajajára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2398,0,NULL,'guc','wayuu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2399,0,NULL,'gud','yocoboué dida','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2400,0,NULL,'gue','gurinji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2401,0,NULL,'guf','gupapuyngu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2402,0,NULL,'gug','paraguayan guaraní','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2403,0,NULL,'guh','guahibo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2404,0,NULL,'gui','eastern bolivian guaraní','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2405,0,NULL,'guk','gumuz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2406,0,NULL,'gul','sea island creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2407,0,NULL,'gum','guambiano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2408,0,NULL,'gun','mbyá guaraní','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2409,0,NULL,'guo','guayabero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2410,0,NULL,'gup','gunwinggu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2411,0,NULL,'guq','aché','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2412,0,NULL,'gur','farefare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2413,0,NULL,'gus','guinean sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2414,0,NULL,'gut','maléku jaíka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2415,0,NULL,'guu','yanomamö','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2416,0,NULL,'guv','gey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2417,0,NULL,'guw','gun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2418,0,NULL,'gux','gourmanchéma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2419,0,NULL,'guz','ekegusii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2419,0,NULL,'guz','gusii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2420,0,NULL,'gva','guana (paraguay)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2421,0,NULL,'gvc','guanano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2422,0,NULL,'gve','duwet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2423,0,NULL,'gvf','golin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2424,0,NULL,'gvj','guajá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2425,0,NULL,'gvl','gulay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2426,0,NULL,'gvm','gurmana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2427,0,NULL,'gvn','kuku-yalanji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2428,0,NULL,'gvo','gavião do jiparaná','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2429,0,NULL,'gvp','pará gavião','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2430,0,NULL,'gvr','western gurung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2431,0,NULL,'gvs','gumawana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2432,0,NULL,'gvy','guyani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2433,0,NULL,'gwa','mbato','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2434,0,NULL,'gwb','gwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2435,0,NULL,'gwc','kalami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2436,0,NULL,'gwd','gawwada','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2437,0,NULL,'gwe','gweno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2438,0,NULL,'gwf','gowro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2439,0,NULL,'gwg','moo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2440,0,NULL,'gwi','gwichʼin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2441,0,NULL,'gwj','/gwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2442,0,NULL,'gwn','gwandara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2443,0,NULL,'gwr','gwere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2444,0,NULL,'gwt','gawar-bati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2445,0,NULL,'gwu','guwamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2446,0,NULL,'gww','kwini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2447,0,NULL,'gwx','gua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2448,0,NULL,'gxx','wè southern','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2449,0,NULL,'gya','northwest gbaya','1248825600',NULL,NULL,NULL,NULL,'gba',NULL,NULL); +INSERT INTO "iana_records" VALUES(2450,0,NULL,'gyb','garus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2451,0,NULL,'gyd','kayardild','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2452,0,NULL,'gye','gyem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2453,0,NULL,'gyf','gungabula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2454,0,NULL,'gyg','gbayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2455,0,NULL,'gyi','gyele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2456,0,NULL,'gyl','gayil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2457,0,NULL,'gym','ngäbere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2458,0,NULL,'gyn','guyanese creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2459,0,NULL,'gyr','guarayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2460,0,NULL,'gyy','gunya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2461,0,NULL,'gza','ganza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2462,0,NULL,'gzi','gazi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2463,0,NULL,'gzn','gane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2464,0,NULL,'haa','han','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2465,0,NULL,'hab','hanoi sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2466,0,NULL,'hac','gurani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2467,0,NULL,'had','hatam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2468,0,NULL,'hae','eastern oromo','1248825600',NULL,NULL,NULL,NULL,'om',NULL,NULL); +INSERT INTO "iana_records" VALUES(2469,0,NULL,'haf','haiphong sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2470,0,NULL,'hag','hanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2471,0,NULL,'hah','hahon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2472,0,NULL,'hai','haida','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2473,0,NULL,'haj','hajong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2474,0,NULL,'hak','hakka chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(2475,0,NULL,'hal','halang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2476,0,NULL,'ham','hewa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2477,0,NULL,'han','hangaza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2478,0,NULL,'hao','hakö','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2479,0,NULL,'hap','hupla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2480,0,NULL,'haq','ha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2481,0,NULL,'har','harari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2482,0,NULL,'has','haisla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2483,0,NULL,'hav','havu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2484,0,NULL,'haw','hawaiian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2485,0,NULL,'hax','southern haida','1248825600',NULL,NULL,NULL,NULL,'hai',NULL,NULL); +INSERT INTO "iana_records" VALUES(2486,0,NULL,'hay','haya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2487,0,NULL,'haz','hazaragi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2488,0,NULL,'hba','hamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2489,0,NULL,'hbb','huba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2490,0,NULL,'hbn','heiban','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2491,0,NULL,'hbo','ancient hebrew','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2492,0,NULL,'hbu','habu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2493,0,NULL,'hca','andaman creole hindi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2494,0,NULL,'hch','huichol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2495,0,NULL,'hdn','northern haida','1248825600',NULL,NULL,NULL,NULL,'hai',NULL,NULL); +INSERT INTO "iana_records" VALUES(2496,0,NULL,'hds','honduras sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2497,0,NULL,'hdy','hadiyya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2498,0,NULL,'hea','northern qiandong miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2499,0,NULL,'hed','herdé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2500,0,NULL,'heg','helong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2501,0,NULL,'heh','hehe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2502,0,NULL,'hei','heiltsuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2503,0,NULL,'hem','hemba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2504,0,NULL,'hgm','hai//om','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2505,0,NULL,'hgw','haigwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2506,0,NULL,'hhi','hoia hoia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2507,0,NULL,'hhr','kerak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2508,0,NULL,'hhy','hoyahoya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2509,0,NULL,'hia','lamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2510,0,NULL,'hib','hibito','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2511,0,NULL,'hid','hidatsa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2512,0,NULL,'hif','fiji hindi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2513,0,NULL,'hig','kamwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2514,0,NULL,'hih','pamosu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2515,0,NULL,'hii','hinduri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2516,0,NULL,'hij','hijuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2517,0,NULL,'hik','seit-kaitetu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2518,0,NULL,'hil','hiligaynon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2519,0,NULL,'him','himachali languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2519,0,NULL,'him','western pahari languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2520,0,NULL,'hio','tsoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2521,0,NULL,'hir','himarimã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2522,0,NULL,'hit','hittite','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2523,0,NULL,'hiw','hiw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2524,0,NULL,'hix','hixkaryána','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2525,0,NULL,'hji','haji','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(2526,0,NULL,'hka','kahe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2527,0,NULL,'hke','hunde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2528,0,NULL,'hkk','hunjara-kaina ke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2529,0,NULL,'hks','heung kong sau yue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2529,0,NULL,'hks','hong kong sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2530,0,NULL,'hla','halia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2531,0,NULL,'hlb','halbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2532,0,NULL,'hld','halang doan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2533,0,NULL,'hle','hlersu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2534,0,NULL,'hlt','nga la','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2535,0,NULL,'hlu','hieroglyphic luwian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2536,0,NULL,'hma','southern mashan hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2536,0,NULL,'hma','southern mashan miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2537,0,NULL,'hmb','humburi senni songhay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2538,0,NULL,'hmc','central huishui hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2538,0,NULL,'hmc','central huishui miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2539,0,NULL,'hmd','a-hmaos','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2539,0,NULL,'hmd','da-hua miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2539,0,NULL,'hmd','large flowery miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2540,0,NULL,'hme','eastern huishui hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2540,0,NULL,'hme','eastern huishui miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2541,0,NULL,'hmf','hmong don','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2542,0,NULL,'hmg','southwestern guiyang hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2543,0,NULL,'hmh','southwestern huishui hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2543,0,NULL,'hmh','southwestern huishui miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2544,0,NULL,'hmi','northern huishui hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2544,0,NULL,'hmi','northern huishui miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2545,0,NULL,'hmj','ge','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2545,0,NULL,'hmj','gejia','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2546,0,NULL,'hmk','maek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2547,0,NULL,'hml','luopohe hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2547,0,NULL,'hml','luopohe miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2548,0,NULL,'hmm','central mashan hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2548,0,NULL,'hmm','central mashan miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2549,0,NULL,'hmn','hmong','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2549,0,NULL,'hmn','mong','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2550,0,NULL,'hmp','northern mashan hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2550,0,NULL,'hmp','northern mashan miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2551,0,NULL,'hmq','eastern qiandong miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2552,0,NULL,'hmr','hmar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2553,0,NULL,'hms','southern qiandong miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2554,0,NULL,'hmt','hamtai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2555,0,NULL,'hmu','hamap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2556,0,NULL,'hmv','hmong dô','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2557,0,NULL,'hmw','western mashan hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2557,0,NULL,'hmw','western mashan miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2558,0,NULL,'hmx','hmong-mien languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2559,0,NULL,'hmy','southern guiyang hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2559,0,NULL,'hmy','southern guiyang miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2560,0,NULL,'hmz','hmong shua','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2560,0,NULL,'hmz','sinicized miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2561,0,NULL,'hna','mina (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2562,0,NULL,'hnd','southern hindko','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(2563,0,NULL,'hne','chhattisgarhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2564,0,NULL,'hnh','//ani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2565,0,NULL,'hni','hani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2566,0,NULL,'hnj','hmong njua','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2566,0,NULL,'hnj','mong leng','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2566,0,NULL,'hnj','mong njua','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2567,0,NULL,'hnn','hanunoo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2568,0,NULL,'hno','northern hindko','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(2569,0,NULL,'hns','caribbean hindustani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2570,0,NULL,'hnu','hung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2571,0,NULL,'hoa','hoava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2572,0,NULL,'hob','mari (madang province)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2573,0,NULL,'hoc','ho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2574,0,NULL,'hod','holma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2575,0,NULL,'hoe','horom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2576,0,NULL,'hoh','hobyót','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2577,0,NULL,'hoi','holikachuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2578,0,NULL,'hoj','hadothi','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(2579,0,NULL,'hok','hokan languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2580,0,NULL,'hol','holu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2581,0,NULL,'hom','homa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2582,0,NULL,'hoo','holoholo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2583,0,NULL,'hop','hopi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2584,0,NULL,'hor','horo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2585,0,NULL,'hos','ho chi minh city sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2586,0,NULL,'hot','hote','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2586,0,NULL,'hot','malê','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2587,0,NULL,'hov','hovongan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2588,0,NULL,'how','honi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2589,0,NULL,'hoy','holiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2590,0,NULL,'hoz','hozo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2591,0,NULL,'hpo','hpon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2592,0,NULL,'hps','hawai''i pidgin sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2593,0,NULL,'hra','hrangkhol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2594,0,NULL,'hre','hre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2595,0,NULL,'hrk','haruku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2596,0,NULL,'hrm','horned miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2597,0,NULL,'hro','haroi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2598,0,NULL,'hrr','horuru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2599,0,NULL,'hrt','hértevin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2600,0,NULL,'hru','hruso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2601,0,NULL,'hrx','hunsrik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2602,0,NULL,'hrz','harzani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2603,0,NULL,'hsb','upper sorbian','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2604,0,NULL,'hsh','hungarian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2605,0,NULL,'hsl','hausa sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2606,0,NULL,'hsn','xiang chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(2607,0,NULL,'hss','harsusi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2608,0,NULL,'hti','hoti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2609,0,NULL,'hto','minica huitoto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2610,0,NULL,'hts','hadza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2611,0,NULL,'htu','hitu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2612,0,NULL,'htx','middle hittite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2613,0,NULL,'hub','huambisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2614,0,NULL,'huc','=/hua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2615,0,NULL,'hud','huaulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2616,0,NULL,'hue','san francisco del mar huave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2617,0,NULL,'huf','humene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2618,0,NULL,'hug','huachipaeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2619,0,NULL,'huh','huilliche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2620,0,NULL,'hui','huli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2621,0,NULL,'huj','northern guiyang hmong','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2621,0,NULL,'huj','northern guiyang miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(2622,0,NULL,'huk','hulung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2623,0,NULL,'hul','hula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2624,0,NULL,'hum','hungana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2625,0,NULL,'huo','hu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2626,0,NULL,'hup','hupa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2627,0,NULL,'huq','tsat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2628,0,NULL,'hur','halkomelem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2629,0,NULL,'hus','huastec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2630,0,NULL,'hut','humla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2631,0,NULL,'huu','murui huitoto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2632,0,NULL,'huv','san mateo del mar huave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2633,0,NULL,'huw','hukumina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2634,0,NULL,'hux','nüpode huitoto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2635,0,NULL,'huy','hulaulá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2636,0,NULL,'huz','hunzib','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2637,0,NULL,'hvc','haitian vodoun culture language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2638,0,NULL,'hve','san dionisio del mar huave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2639,0,NULL,'hvk','haveke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2640,0,NULL,'hvn','sabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2641,0,NULL,'hvv','santa maría del mar huave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2642,0,NULL,'hwa','wané','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2643,0,NULL,'hwc','hawai''i creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2644,0,NULL,'hwo','hwana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2645,0,NULL,'hya','hya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2646,0,NULL,'hyx','armenian (family)','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2647,0,NULL,'iai','iaai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2648,0,NULL,'ian','iatmul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2649,0,NULL,'iap','iapama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2650,0,NULL,'iar','purari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2651,0,NULL,'iba','iban','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2652,0,NULL,'ibb','ibibio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2653,0,NULL,'ibd','iwaidja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2654,0,NULL,'ibe','akpes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2655,0,NULL,'ibg','ibanag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2656,0,NULL,'ibi','ibilo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2657,0,NULL,'ibl','ibaloi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2658,0,NULL,'ibm','agoi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2659,0,NULL,'ibn','ibino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2660,0,NULL,'ibr','ibuoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2661,0,NULL,'ibu','ibu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2662,0,NULL,'iby','ibani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2663,0,NULL,'ica','ede ica','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2664,0,NULL,'ich','etkywan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2665,0,NULL,'icl','icelandic sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2666,0,NULL,'icr','islander creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2667,0,NULL,'ida','idakho-isukha-tiriki','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(2667,0,NULL,'ida','luidakho-luisukha-lutirichi','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(2668,0,NULL,'idb','indo-portuguese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2669,0,NULL,'idc','idon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2670,0,NULL,'idd','ede idaca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2671,0,NULL,'ide','idere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2672,0,NULL,'idi','idi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2673,0,NULL,'idr','indri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2674,0,NULL,'ids','idesa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2675,0,NULL,'idt','idaté','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2676,0,NULL,'idu','idoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2677,0,NULL,'ifa','amganad ifugao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2678,0,NULL,'ifb','ayangan ifugao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2678,0,NULL,'ifb','batad ifugao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2679,0,NULL,'ife','ifè','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2680,0,NULL,'iff','ifo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2681,0,NULL,'ifk','tuwali ifugao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2682,0,NULL,'ifm','teke-fuumu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2683,0,NULL,'ifu','mayoyao ifugao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2684,0,NULL,'ify','keley-i kallahan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2685,0,NULL,'igb','ebira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2686,0,NULL,'ige','igede','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2687,0,NULL,'igg','igana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2688,0,NULL,'igl','igala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2689,0,NULL,'igm','kanggape','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2690,0,NULL,'ign','ignaciano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2691,0,NULL,'igo','isebe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2692,0,NULL,'igs','interglossa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2693,0,NULL,'igw','igwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2694,0,NULL,'ihb','iha based pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2695,0,NULL,'ihi','ihievbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2696,0,NULL,'ihp','iha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2697,0,NULL,'iir','indo-iranian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2698,0,NULL,'ijc','izon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2699,0,NULL,'ije','biseni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2700,0,NULL,'ijj','ede ije','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2701,0,NULL,'ijn','kalabari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2702,0,NULL,'ijo','ijo languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2703,0,NULL,'ijs','southeast ijo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2704,0,NULL,'ike','eastern canadian inuktitut','1248825600',NULL,NULL,NULL,NULL,'iu',NULL,NULL); +INSERT INTO "iana_records" VALUES(2705,0,NULL,'iki','iko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2706,0,NULL,'ikk','ika','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2707,0,NULL,'ikl','ikulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2708,0,NULL,'iko','olulumo-ikom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2709,0,NULL,'ikp','ikpeshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2710,0,NULL,'ikt','western canadian inuktitut','1248825600',NULL,NULL,NULL,NULL,'iu',NULL,NULL); +INSERT INTO "iana_records" VALUES(2711,0,NULL,'ikv','iku-gora-ankwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2712,0,NULL,'ikw','ikwere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2713,0,NULL,'ikx','ik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2714,0,NULL,'ikz','ikizu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2715,0,NULL,'ila','ile ape','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2716,0,NULL,'ilb','ila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2717,0,NULL,'ilg','garig-ilgar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2718,0,NULL,'ili','ili turki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2719,0,NULL,'ilk','ilongot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2720,0,NULL,'ill','iranun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2721,0,NULL,'ilo','iloko','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2722,0,NULL,'ils','international sign','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2723,0,NULL,'ilu','ili''uun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2724,0,NULL,'ilv','ilue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2725,0,NULL,'ilw','talur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2726,0,NULL,'ima','mala malasar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2727,0,NULL,'ime','imeraguen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2728,0,NULL,'imi','anamgura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2729,0,NULL,'iml','miluk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2730,0,NULL,'imn','imonda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2731,0,NULL,'imo','imbongu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2732,0,NULL,'imr','imroing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2733,0,NULL,'ims','marsian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2734,0,NULL,'imy','milyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2735,0,NULL,'inb','inga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2736,0,NULL,'inc','indic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2737,0,NULL,'ine','indo-european languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2738,0,NULL,'ing','degexit''an','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2739,0,NULL,'inh','ingush','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2740,0,NULL,'inj','jungle inga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2741,0,NULL,'inl','indonesian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2742,0,NULL,'inm','minaean','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2743,0,NULL,'inn','isinai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2744,0,NULL,'ino','inoke-yate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2745,0,NULL,'inp','iñapari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2746,0,NULL,'ins','indian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2747,0,NULL,'int','intha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2748,0,NULL,'inz','ineseño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2749,0,NULL,'ior','inor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2750,0,NULL,'iou','tuma-irumu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2751,0,NULL,'iow','iowa-oto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2752,0,NULL,'ipi','ipili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2753,0,NULL,'ipo','ipiko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2754,0,NULL,'iqu','iquito','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2755,0,NULL,'ira','iranian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2756,0,NULL,'ire','iresim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2757,0,NULL,'irh','irarutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2758,0,NULL,'iri','irigwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2759,0,NULL,'irk','iraqw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2760,0,NULL,'irn','irántxe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2761,0,NULL,'iro','iroquoian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2762,0,NULL,'irr','ir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2763,0,NULL,'iru','irula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2764,0,NULL,'irx','kamberau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2765,0,NULL,'iry','iraya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2766,0,NULL,'isa','isabi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2767,0,NULL,'isc','isconahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2768,0,NULL,'isd','isnag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2769,0,NULL,'ise','italian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2770,0,NULL,'isg','irish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2771,0,NULL,'ish','esan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2772,0,NULL,'isi','nkem-nkum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2773,0,NULL,'isk','ishkashimi','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2774,0,NULL,'ism','masimasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2775,0,NULL,'isn','isanzu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2776,0,NULL,'iso','isoko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2777,0,NULL,'isr','israeli sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2778,0,NULL,'ist','istriot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2779,0,NULL,'isu','isu (menchum division)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2780,0,NULL,'itb','binongan itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2781,0,NULL,'itc','italic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2782,0,NULL,'ite','itene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2783,0,NULL,'iti','inlaod itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2784,0,NULL,'itk','judeo-italian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2785,0,NULL,'itl','itelmen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2786,0,NULL,'itm','itu mbon uzo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2787,0,NULL,'ito','itonama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2788,0,NULL,'itr','iteri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2789,0,NULL,'its','isekiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2790,0,NULL,'itt','maeng itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2791,0,NULL,'itv','itawit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2792,0,NULL,'itw','ito','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2793,0,NULL,'itx','itik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2794,0,NULL,'ity','moyadan itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2795,0,NULL,'itz','itzá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2796,0,NULL,'ium','iu mien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2797,0,NULL,'ivb','ibatan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2798,0,NULL,'ivv','ivatan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2799,0,NULL,'iwk','i-wak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2800,0,NULL,'iwm','iwam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2801,0,NULL,'iwo','iwur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2802,0,NULL,'iws','sepik iwam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2803,0,NULL,'ixc','ixcatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2804,0,NULL,'ixl','ixil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2805,0,NULL,'iya','iyayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2806,0,NULL,'iyo','mesaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2807,0,NULL,'iyx','yaka (congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2808,0,NULL,'izh','ingrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2809,0,NULL,'izi','izi-ezaa-ikwo-mgbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2810,0,NULL,'izr','izere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2811,0,NULL,'jaa','jamamadí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2812,0,NULL,'jab','hyam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2813,0,NULL,'jac','jakalteko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2813,0,NULL,'jac','popti''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2814,0,NULL,'jad','jahanka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2815,0,NULL,'jae','yabem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2816,0,NULL,'jaf','jara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2817,0,NULL,'jah','jah hut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2818,0,NULL,'jaj','zazao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2819,0,NULL,'jak','jakun','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(2820,0,NULL,'jal','yalahatan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2821,0,NULL,'jam','jamaican creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2822,0,NULL,'jao','yanyuwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2823,0,NULL,'jaq','yaqay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2824,0,NULL,'jar','jarawa (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2825,0,NULL,'jas','new caledonian javanese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2826,0,NULL,'jat','jakati','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(2827,0,NULL,'jau','yaur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2828,0,NULL,'jax','jambi malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(2829,0,NULL,'jay','yan-nhangu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2830,0,NULL,'jaz','jawe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2831,0,NULL,'jbe','judeo-berber','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2832,0,NULL,'jbj','arandai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2833,0,NULL,'jbn','nafusi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2834,0,NULL,'jbo','lojban','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2835,0,NULL,'jbr','jofotek-bromnya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2836,0,NULL,'jbt','jabutí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2837,0,NULL,'jbu','jukun takum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2838,0,NULL,'jcs','jamaican country sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2839,0,NULL,'jct','krymchak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2840,0,NULL,'jda','jad','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2841,0,NULL,'jdg','jadgali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2842,0,NULL,'jdt','judeo-tat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2843,0,NULL,'jeb','jebero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2844,0,NULL,'jee','jerung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2845,0,NULL,'jeg','jeng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2846,0,NULL,'jeh','jeh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2847,0,NULL,'jei','yei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2848,0,NULL,'jek','jeri kuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2849,0,NULL,'jel','yelmek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2850,0,NULL,'jen','dza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2851,0,NULL,'jer','jere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2852,0,NULL,'jet','manem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2853,0,NULL,'jeu','jonkor bourmataguil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2854,0,NULL,'jgb','ngbee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2855,0,NULL,'jge','judeo-georgian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2856,0,NULL,'jgo','ngomba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2857,0,NULL,'jhi','jehai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2858,0,NULL,'jhs','jhankot sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2859,0,NULL,'jia','jina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2860,0,NULL,'jib','jibu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2861,0,NULL,'jic','tol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2862,0,NULL,'jid','bu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2863,0,NULL,'jie','jilbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2864,0,NULL,'jig','djingili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2865,0,NULL,'jih','shangzhai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2866,0,NULL,'jii','jiiddu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2867,0,NULL,'jil','jilim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2868,0,NULL,'jim','jimi (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2869,0,NULL,'jio','jiamao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2870,0,NULL,'jiq','guanyinqiao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2871,0,NULL,'jit','jita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2872,0,NULL,'jiu','youle jinuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2873,0,NULL,'jiv','shuar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2874,0,NULL,'jiy','buyuan jinuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2875,0,NULL,'jko','kubo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2876,0,NULL,'jku','labir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2877,0,NULL,'jle','ngile','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2878,0,NULL,'jls','jamaican sign language','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2879,0,NULL,'jma','dima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2880,0,NULL,'jmb','zumbun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2881,0,NULL,'jmc','machame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2882,0,NULL,'jmd','yamdena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2883,0,NULL,'jmi','jimi (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2884,0,NULL,'jml','jumli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2885,0,NULL,'jmn','makuri naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2886,0,NULL,'jmr','kamara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2887,0,NULL,'jms','mashi (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2888,0,NULL,'jmx','western juxtlahuaca mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2889,0,NULL,'jna','jangshung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2890,0,NULL,'jnd','jandavra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2891,0,NULL,'jng','yangman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2892,0,NULL,'jni','janji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2893,0,NULL,'jnj','yemsa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2894,0,NULL,'jnl','rawat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2895,0,NULL,'jns','jaunsari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2896,0,NULL,'job','joba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2897,0,NULL,'jod','wojenaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2898,0,NULL,'jor','jorá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2899,0,NULL,'jos','jordanian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2900,0,NULL,'jow','jowulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2901,0,NULL,'jpa','jewish palestinian aramaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2902,0,NULL,'jpr','judeo-persian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2903,0,NULL,'jpx','japanese (family)','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2904,0,NULL,'jqr','jaqaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2905,0,NULL,'jra','jarai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2906,0,NULL,'jrb','judeo-arabic','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(2907,0,NULL,'jrr','jiru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2908,0,NULL,'jrt','jorto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2909,0,NULL,'jru','japrería','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2910,0,NULL,'jsl','japanese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2911,0,NULL,'jua','júma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2912,0,NULL,'jub','wannu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2913,0,NULL,'juc','jurchen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2914,0,NULL,'jud','worodougou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2915,0,NULL,'juh','hõne','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2916,0,NULL,'juk','wapan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2917,0,NULL,'jul','jirel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2918,0,NULL,'jum','jumjum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2919,0,NULL,'jun','juang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2920,0,NULL,'juo','jiba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2921,0,NULL,'jup','hupdë','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2922,0,NULL,'jur','jurúna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2923,0,NULL,'jus','jumla sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2924,0,NULL,'jut','jutish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2925,0,NULL,'juu','ju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2926,0,NULL,'juw','wãpha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2927,0,NULL,'juy','juray','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2928,0,NULL,'jvd','javindo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2929,0,NULL,'jvn','caribbean javanese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2930,0,NULL,'jwi','jwira-pepesa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2931,0,NULL,'jya','jiarong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2932,0,NULL,'jye','judeo-yemeni arabic','1248825600',NULL,NULL,NULL,NULL,'jrb',NULL,NULL); +INSERT INTO "iana_records" VALUES(2933,0,NULL,'jyy','jaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2934,0,NULL,'kaa','kara-kalpak','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2935,0,NULL,'kab','kabyle','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2936,0,NULL,'kac','jingpho','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2936,0,NULL,'kac','kachin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2937,0,NULL,'kad','kadara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2938,0,NULL,'kae','ketangalan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2939,0,NULL,'kaf','katso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2940,0,NULL,'kag','kajaman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2941,0,NULL,'kah','kara (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2942,0,NULL,'kai','karekare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2943,0,NULL,'kaj','jju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2944,0,NULL,'kak','kayapa kallahan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2945,0,NULL,'kam','kamba (kenya)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2946,0,NULL,'kao','xaasongaxango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2947,0,NULL,'kap','bezhta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2948,0,NULL,'kaq','capanahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2949,0,NULL,'kar','karen languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(2950,0,NULL,'kav','katukína','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2951,0,NULL,'kaw','kawi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2952,0,NULL,'kax','kao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2953,0,NULL,'kay','kamayurá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2954,0,NULL,'kba','kalarko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2955,0,NULL,'kbb','kaxuiâna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2956,0,NULL,'kbc','kadiwéu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2957,0,NULL,'kbd','kabardian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2958,0,NULL,'kbe','kanju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2959,0,NULL,'kbf','kakauhua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2960,0,NULL,'kbg','khamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2961,0,NULL,'kbh','camsá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2962,0,NULL,'kbi','kaptiau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2963,0,NULL,'kbj','kari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2964,0,NULL,'kbk','grass koiari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2965,0,NULL,'kbl','kanembu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2966,0,NULL,'kbm','iwal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2967,0,NULL,'kbn','kare (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2968,0,NULL,'kbo','keliko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2969,0,NULL,'kbp','kabiyè','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2970,0,NULL,'kbq','kamano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2971,0,NULL,'kbr','kafa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2972,0,NULL,'kbs','kande','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2973,0,NULL,'kbt','abadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2974,0,NULL,'kbu','kabutra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2975,0,NULL,'kbv','dera (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2976,0,NULL,'kbw','kaiep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2977,0,NULL,'kbx','ap ma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2978,0,NULL,'kby','manga kanuri','1248825600',NULL,NULL,NULL,NULL,'kr',NULL,NULL); +INSERT INTO "iana_records" VALUES(2979,0,NULL,'kbz','duhwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2980,0,NULL,'kca','khanty','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2981,0,NULL,'kcb','kawacha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2982,0,NULL,'kcc','lubila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2983,0,NULL,'kcd','ngkâlmpw kanum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2984,0,NULL,'kce','kaivi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2985,0,NULL,'kcf','ukaan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2986,0,NULL,'kcg','tyap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2987,0,NULL,'kch','vono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2988,0,NULL,'kci','kamantan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2989,0,NULL,'kcj','kobiana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2990,0,NULL,'kck','kalanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2991,0,NULL,'kcl','kela (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2992,0,NULL,'kcm','gula (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2993,0,NULL,'kcn','nubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2994,0,NULL,'kco','kinalakna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2995,0,NULL,'kcp','kanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2996,0,NULL,'kcq','kamo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2997,0,NULL,'kcr','katla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2998,0,NULL,'kcs','koenoem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(2999,0,NULL,'kct','kaian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3000,0,NULL,'kcu','kami (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3001,0,NULL,'kcv','kete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3002,0,NULL,'kcw','kabwari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3003,0,NULL,'kcx','kachama-ganjule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3004,0,NULL,'kcy','korandje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3005,0,NULL,'kcz','konongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3006,0,NULL,'kda','worimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3007,0,NULL,'kdc','kutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3008,0,NULL,'kdd','yankunytjatjara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3009,0,NULL,'kde','makonde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3010,0,NULL,'kdf','mamusi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3011,0,NULL,'kdg','seba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3012,0,NULL,'kdh','tem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3013,0,NULL,'kdi','kumam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3014,0,NULL,'kdj','karamojong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3015,0,NULL,'kdk','numee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3016,0,NULL,'kdl','tsikimba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3017,0,NULL,'kdm','kagoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3018,0,NULL,'kdn','kunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3019,0,NULL,'kdo','kordofanian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(3020,0,NULL,'kdp','kaningdon-nindem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3021,0,NULL,'kdq','koch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3022,0,NULL,'kdr','karaim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3023,0,NULL,'kdt','kuy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3024,0,NULL,'kdu','kadaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3025,0,NULL,'kdv','kado','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3026,0,NULL,'kdw','koneraw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3027,0,NULL,'kdx','kam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3028,0,NULL,'kdy','keder','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3028,0,NULL,'kdy','keijar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3029,0,NULL,'kdz','kwaja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3030,0,NULL,'kea','kabuverdianu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3031,0,NULL,'keb','kélé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3032,0,NULL,'kec','keiga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3033,0,NULL,'ked','kerewe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3034,0,NULL,'kee','eastern keres','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3035,0,NULL,'kef','kpessi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3036,0,NULL,'keg','tese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3037,0,NULL,'keh','keak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3038,0,NULL,'kei','kei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3039,0,NULL,'kej','kadar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3040,0,NULL,'kek','kekchí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3041,0,NULL,'kel','kela (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3042,0,NULL,'kem','kemak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3043,0,NULL,'ken','kenyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3044,0,NULL,'keo','kakwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3045,0,NULL,'kep','kaikadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3046,0,NULL,'keq','kamar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3047,0,NULL,'ker','kera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3048,0,NULL,'kes','kugbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3049,0,NULL,'ket','ket','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3050,0,NULL,'keu','akebu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3051,0,NULL,'kev','kanikkaran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3052,0,NULL,'kew','west kewa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3053,0,NULL,'kex','kukna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3054,0,NULL,'key','kupia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3055,0,NULL,'kez','kukele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3056,0,NULL,'kfa','kodava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3057,0,NULL,'kfb','northwestern kolami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3058,0,NULL,'kfc','konda-dora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3059,0,NULL,'kfd','korra koraga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3060,0,NULL,'kfe','kota (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3061,0,NULL,'kff','koya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3062,0,NULL,'kfg','kudiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3063,0,NULL,'kfh','kurichiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3064,0,NULL,'kfi','kannada kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3065,0,NULL,'kfj','kemiehua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3066,0,NULL,'kfk','kinnauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3067,0,NULL,'kfl','kung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3068,0,NULL,'kfm','khunsari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3069,0,NULL,'kfn','kuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3070,0,NULL,'kfo','koro (côte d''ivoire)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3071,0,NULL,'kfp','korwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3072,0,NULL,'kfq','korku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3073,0,NULL,'kfr','kachchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3074,0,NULL,'kfs','bilaspuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3075,0,NULL,'kft','kanjari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3076,0,NULL,'kfu','katkari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3077,0,NULL,'kfv','kurmukar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3078,0,NULL,'kfw','kharam naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3079,0,NULL,'kfx','kullu pahari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3080,0,NULL,'kfy','kumaoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3081,0,NULL,'kfz','koromfé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3082,0,NULL,'kga','koyaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3083,0,NULL,'kgb','kawe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3084,0,NULL,'kgc','kasseng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3085,0,NULL,'kgd','kataang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3086,0,NULL,'kge','komering','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3087,0,NULL,'kgf','kube','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3088,0,NULL,'kgg','kusunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3089,0,NULL,'kgh','upper tanudan kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3090,0,NULL,'kgi','selangor sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3091,0,NULL,'kgj','gamale kham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3092,0,NULL,'kgk','kaiwá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3093,0,NULL,'kgl','kunggari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3094,0,NULL,'kgm','karipúna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3095,0,NULL,'kgn','karingani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3096,0,NULL,'kgo','krongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3097,0,NULL,'kgp','kaingang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3098,0,NULL,'kgq','kamoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3099,0,NULL,'kgr','abun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3100,0,NULL,'kgs','kumbainggar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3101,0,NULL,'kgt','somyev','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3102,0,NULL,'kgu','kobol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3103,0,NULL,'kgv','karas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3104,0,NULL,'kgw','karon dori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3105,0,NULL,'kgx','kamaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3106,0,NULL,'kgy','kyerung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3107,0,NULL,'kha','khasi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,'as of 2008-04-21 this subtag does not include lyngngam; see lyg'); +INSERT INTO "iana_records" VALUES(3108,0,NULL,'khb','lü','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3109,0,NULL,'khc','tukang besi north','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3110,0,NULL,'khd','bädi kanum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3111,0,NULL,'khe','korowai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3112,0,NULL,'khf','khuen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3113,0,NULL,'khg','khams tibetan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3114,0,NULL,'khh','kehu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3115,0,NULL,'khi','khoisan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(3116,0,NULL,'khj','kuturmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3117,0,NULL,'khk','halh mongolian','1248825600',NULL,NULL,NULL,NULL,'mn',NULL,NULL); +INSERT INTO "iana_records" VALUES(3118,0,NULL,'khl','lusi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3119,0,NULL,'khn','khandesi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3120,0,NULL,'kho','khotanese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3120,0,NULL,'kho','sakan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3121,0,NULL,'khp','kapauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3121,0,NULL,'khp','kapori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3122,0,NULL,'khq','koyra chiini songhay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3123,0,NULL,'khr','kharia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3124,0,NULL,'khs','kasua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3125,0,NULL,'kht','khamti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3126,0,NULL,'khu','nkhumbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3127,0,NULL,'khv','khvarshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3128,0,NULL,'khw','khowar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3129,0,NULL,'khx','kanu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3130,0,NULL,'khy','kele (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3131,0,NULL,'khz','keapara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3132,0,NULL,'kia','kim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3133,0,NULL,'kib','koalib','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3134,0,NULL,'kic','kickapoo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3135,0,NULL,'kid','koshin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3136,0,NULL,'kie','kibet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3137,0,NULL,'kif','eastern parbate kham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3138,0,NULL,'kig','kimaama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3138,0,NULL,'kig','kimaghima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3139,0,NULL,'kih','kilmeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3140,0,NULL,'kii','kitsai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3141,0,NULL,'kij','kilivila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3142,0,NULL,'kil','kariya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3143,0,NULL,'kim','karagas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3144,0,NULL,'kio','kiowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3145,0,NULL,'kip','sheshi kham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3146,0,NULL,'kiq','kosadle','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3146,0,NULL,'kiq','kosare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3147,0,NULL,'kis','kis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3148,0,NULL,'kit','agob','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3149,0,NULL,'kiu','kirmanjki (individual language)','1248825600',NULL,NULL,NULL,NULL,'zza',NULL,NULL); +INSERT INTO "iana_records" VALUES(3150,0,NULL,'kiv','kimbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3151,0,NULL,'kiw','northeast kiwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3152,0,NULL,'kix','khiamniungan naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3153,0,NULL,'kiy','kirikiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3154,0,NULL,'kiz','kisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3155,0,NULL,'kja','mlap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3156,0,NULL,'kjb','kanjobal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3156,0,NULL,'kjb','q''anjob''al','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3157,0,NULL,'kjc','coastal konjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3158,0,NULL,'kjd','southern kiwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3159,0,NULL,'kje','kisar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3160,0,NULL,'kjf','khalaj','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3161,0,NULL,'kjg','khmu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3162,0,NULL,'kjh','khakas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3163,0,NULL,'kji','zabana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3164,0,NULL,'kjj','khinalugh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3165,0,NULL,'kjk','highland konjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3166,0,NULL,'kjl','western parbate kham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3167,0,NULL,'kjm','kháng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3168,0,NULL,'kjn','kunjen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3169,0,NULL,'kjo','harijan kinnauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3170,0,NULL,'kjp','pwo eastern karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3171,0,NULL,'kjq','western keres','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3172,0,NULL,'kjr','kurudu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3173,0,NULL,'kjs','east kewa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3174,0,NULL,'kjt','phrae pwo karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3175,0,NULL,'kju','kashaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3176,0,NULL,'kjx','ramopa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3177,0,NULL,'kjy','erave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3178,0,NULL,'kjz','bumthangkha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3179,0,NULL,'kka','kakanda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3180,0,NULL,'kkb','kwerisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3181,0,NULL,'kkc','odoodee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3182,0,NULL,'kkd','kinuku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3183,0,NULL,'kke','kakabe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3184,0,NULL,'kkf','kalaktang monpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3185,0,NULL,'kkg','mabaka valley kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3186,0,NULL,'kkh','khün','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3187,0,NULL,'kki','kagulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3188,0,NULL,'kkj','kako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3189,0,NULL,'kkk','kokota','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3190,0,NULL,'kkl','kosarek yale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3191,0,NULL,'kkm','kiong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3192,0,NULL,'kkn','kon keu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3193,0,NULL,'kko','karko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3194,0,NULL,'kkp','gugubera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3195,0,NULL,'kkq','kaiku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3196,0,NULL,'kkr','kir-balar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3197,0,NULL,'kks','giiwo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3198,0,NULL,'kkt','koi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3199,0,NULL,'kku','tumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3200,0,NULL,'kkv','kangean','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3201,0,NULL,'kkw','teke-kukuya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3202,0,NULL,'kkx','kohin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3203,0,NULL,'kky','guguyimidjir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3204,0,NULL,'kkz','kaska','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3205,0,NULL,'kla','klamath-modoc','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3206,0,NULL,'klb','kiliwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3207,0,NULL,'klc','kolbila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3208,0,NULL,'kld','gamilaraay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3209,0,NULL,'kle','kulung (nepal)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3210,0,NULL,'klf','kendeje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3211,0,NULL,'klg','tagakaulo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3212,0,NULL,'klh','weliki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3213,0,NULL,'kli','kalumpang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3214,0,NULL,'klj','turkic khalaj','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3215,0,NULL,'klk','kono (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3216,0,NULL,'kll','kagan kalagan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3217,0,NULL,'klm','migum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3218,0,NULL,'kln','kalenjin','1248825600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3219,0,NULL,'klo','kapya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3220,0,NULL,'klp','kamasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3221,0,NULL,'klq','rumu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3222,0,NULL,'klr','khaling','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3223,0,NULL,'kls','kalasha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3224,0,NULL,'klt','nukna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3225,0,NULL,'klu','klao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3226,0,NULL,'klv','maskelynes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3227,0,NULL,'klw','lindu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3228,0,NULL,'klx','koluwawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3229,0,NULL,'kly','kalao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3230,0,NULL,'klz','kabola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3231,0,NULL,'kma','konni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3232,0,NULL,'kmb','kimbundu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3233,0,NULL,'kmc','southern dong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3234,0,NULL,'kmd','majukayang kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3235,0,NULL,'kme','bakole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3236,0,NULL,'kmf','kare (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3237,0,NULL,'kmg','kâte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3238,0,NULL,'kmh','kalam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3239,0,NULL,'kmi','kami (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3240,0,NULL,'kmj','kumarbhag paharia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3241,0,NULL,'kmk','limos kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3242,0,NULL,'kml','lower tanudan kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3243,0,NULL,'kmm','kom (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3244,0,NULL,'kmn','awtuw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3245,0,NULL,'kmo','kwoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3246,0,NULL,'kmp','gimme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3247,0,NULL,'kmq','kwama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3248,0,NULL,'kmr','northern kurdish','1248825600',NULL,NULL,NULL,NULL,'ku',NULL,NULL); +INSERT INTO "iana_records" VALUES(3249,0,NULL,'kms','kamasau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3250,0,NULL,'kmt','kemtuik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3251,0,NULL,'kmu','kanite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3252,0,NULL,'kmv','karipúna creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3253,0,NULL,'kmw','komo (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3254,0,NULL,'kmx','waboda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3255,0,NULL,'kmy','koma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3256,0,NULL,'kmz','khorasani turkish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3257,0,NULL,'kna','dera (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3258,0,NULL,'knb','lubuagan kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3259,0,NULL,'knc','central kanuri','1248825600',NULL,NULL,NULL,NULL,'kr',NULL,NULL); +INSERT INTO "iana_records" VALUES(3260,0,NULL,'knd','konda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3261,0,NULL,'kne','kankanaey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3262,0,NULL,'knf','mankanya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3263,0,NULL,'kng','koongo','1248825600',NULL,NULL,NULL,NULL,'kg',NULL,NULL); +INSERT INTO "iana_records" VALUES(3264,0,NULL,'kni','kanufi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3265,0,NULL,'knj','western kanjobal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3266,0,NULL,'knk','kuranko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3267,0,NULL,'knl','keninjal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3268,0,NULL,'knm','kanamarí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3269,0,NULL,'knn','konkani (individual language)','1248825600',NULL,NULL,NULL,NULL,'kok',NULL,NULL); +INSERT INTO "iana_records" VALUES(3270,0,NULL,'kno','kono (sierra leone)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3271,0,NULL,'knp','kwanja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3272,0,NULL,'knq','kintaq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3273,0,NULL,'knr','kaningra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3274,0,NULL,'kns','kensiu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3275,0,NULL,'knt','panoan katukína','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3276,0,NULL,'knu','kono (guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3277,0,NULL,'knv','tabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3278,0,NULL,'knw','kung-ekoka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3279,0,NULL,'knx','kendayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3279,0,NULL,'knx','salako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3280,0,NULL,'kny','kanyok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3281,0,NULL,'knz','kalamsé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3282,0,NULL,'koa','konomala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3283,0,NULL,'koc','kpati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3284,0,NULL,'kod','kodi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3285,0,NULL,'koe','kacipo-balesi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3286,0,NULL,'kof','kubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3287,0,NULL,'kog','cogui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3287,0,NULL,'kog','kogi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3288,0,NULL,'koh','koyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3289,0,NULL,'koi','komi-permyak','1248825600',NULL,NULL,NULL,NULL,'kv',NULL,NULL); +INSERT INTO "iana_records" VALUES(3290,0,NULL,'koj','sara dunjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3291,0,NULL,'kok','konkani (macrolanguage)','1129420800',NULL,NULL,NULL,'deva',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3292,0,NULL,'kol','kol (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3293,0,NULL,'koo','konzo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3294,0,NULL,'kop','kwato','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3295,0,NULL,'koq','kota (gabon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3296,0,NULL,'kos','kosraean','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3297,0,NULL,'kot','lagwan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3298,0,NULL,'kou','koke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3299,0,NULL,'kov','kudu-camo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3300,0,NULL,'kow','kugama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3301,0,NULL,'kox','coxima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3302,0,NULL,'koy','koyukon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3303,0,NULL,'koz','korak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3304,0,NULL,'kpa','kutto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3305,0,NULL,'kpb','mullu kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3306,0,NULL,'kpc','curripaco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3307,0,NULL,'kpd','koba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3308,0,NULL,'kpe','kpelle','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3309,0,NULL,'kpf','komba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3310,0,NULL,'kpg','kapingamarangi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3311,0,NULL,'kph','kplang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3312,0,NULL,'kpi','kofei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3313,0,NULL,'kpj','karajá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3314,0,NULL,'kpk','kpan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3315,0,NULL,'kpl','kpala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3316,0,NULL,'kpm','koho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3317,0,NULL,'kpn','kepkiriwát','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3318,0,NULL,'kpo','ikposo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3319,0,NULL,'kpp','paku karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3320,0,NULL,'kpq','korupun-sela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3321,0,NULL,'kpr','korafe-yegha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3322,0,NULL,'kps','tehit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3323,0,NULL,'kpt','karata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3324,0,NULL,'kpu','kafoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3325,0,NULL,'kpv','komi-zyrian','1248825600',NULL,NULL,NULL,NULL,'kv',NULL,NULL); +INSERT INTO "iana_records" VALUES(3326,0,NULL,'kpw','kobon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3327,0,NULL,'kpx','mountain koiali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3328,0,NULL,'kpy','koryak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3329,0,NULL,'kpz','kupsabiny','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3330,0,NULL,'kqa','mum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3331,0,NULL,'kqb','kovai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3332,0,NULL,'kqc','doromu-koki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3333,0,NULL,'kqd','koy sanjaq surat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3334,0,NULL,'kqe','kalagan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3335,0,NULL,'kqf','kakabai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3336,0,NULL,'kqg','khe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3337,0,NULL,'kqh','kisankasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3338,0,NULL,'kqi','koitabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3339,0,NULL,'kqj','koromira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3340,0,NULL,'kqk','kotafon gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3341,0,NULL,'kql','kyenele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3342,0,NULL,'kqm','khisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3343,0,NULL,'kqn','kaonde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3344,0,NULL,'kqo','eastern krahn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3345,0,NULL,'kqp','kimré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3346,0,NULL,'kqq','krenak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3347,0,NULL,'kqr','kimaragang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3348,0,NULL,'kqs','northern kissi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3349,0,NULL,'kqt','klias river kadazan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3350,0,NULL,'kqu','seroa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3351,0,NULL,'kqv','okolod','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3352,0,NULL,'kqw','kandas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3353,0,NULL,'kqx','mser','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3354,0,NULL,'kqy','koorete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3355,0,NULL,'kqz','korana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3356,0,NULL,'kra','kumhali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3357,0,NULL,'krb','karkin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3358,0,NULL,'krc','karachay-balkar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3359,0,NULL,'krd','kairui-midiki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3360,0,NULL,'kre','panará','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3361,0,NULL,'krf','koro (vanuatu)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3362,0,NULL,'krh','kurama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3363,0,NULL,'kri','krio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3364,0,NULL,'krj','kinaray-a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3365,0,NULL,'krk','kerek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3366,0,NULL,'krl','karelian','1141776000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3367,0,NULL,'krm','krim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3368,0,NULL,'krn','sapo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3369,0,NULL,'kro','kru languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(3370,0,NULL,'krp','korop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3371,0,NULL,'krr','kru''ng 2','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3372,0,NULL,'krs','gbaya (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3373,0,NULL,'krt','tumari kanuri','1248825600',NULL,NULL,NULL,NULL,'kr',NULL,NULL); +INSERT INTO "iana_records" VALUES(3374,0,NULL,'kru','kurukh','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3375,0,NULL,'krv','kavet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3376,0,NULL,'krw','western krahn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3377,0,NULL,'krx','karon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3378,0,NULL,'kry','kryts','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3379,0,NULL,'krz','sota kanum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3380,0,NULL,'ksa','shuwa-zamani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3381,0,NULL,'ksb','shambala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3382,0,NULL,'ksc','southern kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3383,0,NULL,'ksd','kuanua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3384,0,NULL,'kse','kuni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3385,0,NULL,'ksf','bafia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3386,0,NULL,'ksg','kusaghe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3387,0,NULL,'ksh','kölsch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3388,0,NULL,'ksi','i''saka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3388,0,NULL,'ksi','krisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3389,0,NULL,'ksj','uare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3390,0,NULL,'ksk','kansa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3391,0,NULL,'ksl','kumalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3392,0,NULL,'ksm','kumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3393,0,NULL,'ksn','kasiguranin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3394,0,NULL,'kso','kofa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3395,0,NULL,'ksp','kaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3396,0,NULL,'ksq','kwaami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3397,0,NULL,'ksr','borong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3398,0,NULL,'kss','southern kisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3399,0,NULL,'kst','winyé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3400,0,NULL,'ksu','khamyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3401,0,NULL,'ksv','kusu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3402,0,NULL,'ksw','s''gaw karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3403,0,NULL,'ksx','kedang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3404,0,NULL,'ksy','kharia thar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3405,0,NULL,'ksz','kodaku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3406,0,NULL,'kta','katua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3407,0,NULL,'ktb','kambaata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3408,0,NULL,'ktc','kholok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3409,0,NULL,'ktd','kokata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3410,0,NULL,'kte','nubri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3411,0,NULL,'ktf','kwami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3412,0,NULL,'ktg','kalkutung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3413,0,NULL,'kth','karanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3414,0,NULL,'kti','north muyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3415,0,NULL,'ktj','plapo krumen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3416,0,NULL,'ktk','kaniet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3417,0,NULL,'ktl','koroshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3418,0,NULL,'ktm','kurti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3419,0,NULL,'ktn','karitiâna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3420,0,NULL,'kto','kuot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3421,0,NULL,'ktp','kaduo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3422,0,NULL,'ktq','katabaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3423,0,NULL,'ktr','kota marudu tinagas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3424,0,NULL,'kts','south muyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3425,0,NULL,'ktt','ketum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3426,0,NULL,'ktu','kituba (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3427,0,NULL,'ktv','eastern katu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3428,0,NULL,'ktw','kato','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3429,0,NULL,'ktx','kaxararí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3430,0,NULL,'kty','kango (bas-uélé district)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3431,0,NULL,'ktz','ju/''hoan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3432,0,NULL,'kub','kutep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3433,0,NULL,'kuc','kwinsu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3434,0,NULL,'kud','''auhelawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3435,0,NULL,'kue','kuman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3436,0,NULL,'kuf','western katu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3437,0,NULL,'kug','kupa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3438,0,NULL,'kuh','kushi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3439,0,NULL,'kui','kuikúro-kalapálo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3440,0,NULL,'kuj','kuria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3441,0,NULL,'kuk','kepo''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3442,0,NULL,'kul','kulere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3443,0,NULL,'kum','kumyk','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3444,0,NULL,'kun','kunama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3445,0,NULL,'kuo','kumukio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3446,0,NULL,'kup','kunimaipa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3447,0,NULL,'kuq','karipuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3448,0,NULL,'kus','kusaal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3449,0,NULL,'kut','kutenai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3450,0,NULL,'kuu','upper kuskokwim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3451,0,NULL,'kuv','kur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3452,0,NULL,'kuw','kpagua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3453,0,NULL,'kux','kukatja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3454,0,NULL,'kuy','kuuku-ya''u','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3455,0,NULL,'kuz','kunza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3456,0,NULL,'kva','bagvalal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3457,0,NULL,'kvb','kubu','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3458,0,NULL,'kvc','kove','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3459,0,NULL,'kvd','kui (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3460,0,NULL,'kve','kalabakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3461,0,NULL,'kvf','kabalai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3462,0,NULL,'kvg','kuni-boazi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3463,0,NULL,'kvh','komodo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3464,0,NULL,'kvi','kwang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3465,0,NULL,'kvj','psikye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3466,0,NULL,'kvk','korean sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3467,0,NULL,'kvl','brek karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3468,0,NULL,'kvm','kendem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3469,0,NULL,'kvn','border kuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3470,0,NULL,'kvo','dobel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3471,0,NULL,'kvp','kompane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3472,0,NULL,'kvq','geba karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3473,0,NULL,'kvr','kerinci','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3474,0,NULL,'kvs','kunggara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3475,0,NULL,'kvt','lahta karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3476,0,NULL,'kvu','yinbaw karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3477,0,NULL,'kvv','kola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3478,0,NULL,'kvw','wersing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3479,0,NULL,'kvx','parkari koli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3480,0,NULL,'kvy','yintale karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3481,0,NULL,'kvz','tsakwambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3481,0,NULL,'kvz','tsaukambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3482,0,NULL,'kwa','dâw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3483,0,NULL,'kwb','kwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3484,0,NULL,'kwc','likwala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3485,0,NULL,'kwd','kwaio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3486,0,NULL,'kwe','kwerba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3487,0,NULL,'kwf','kwara''ae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3488,0,NULL,'kwg','sara kaba deme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3489,0,NULL,'kwh','kowiai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3490,0,NULL,'kwi','awa-cuaiquer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3491,0,NULL,'kwj','kwanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3492,0,NULL,'kwk','kwakiutl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3493,0,NULL,'kwl','kofyar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3494,0,NULL,'kwm','kwambi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3495,0,NULL,'kwn','kwangali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3496,0,NULL,'kwo','kwomtari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3497,0,NULL,'kwp','kodia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3498,0,NULL,'kwq','kwak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3499,0,NULL,'kwr','kwer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3500,0,NULL,'kws','kwese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3501,0,NULL,'kwt','kwesten','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3502,0,NULL,'kwu','kwakum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3503,0,NULL,'kwv','sara kaba náà','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3504,0,NULL,'kww','kwinti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3505,0,NULL,'kwx','khirwar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3506,0,NULL,'kwy','san salvador kongo','1248825600',NULL,NULL,NULL,NULL,'kg',NULL,NULL); +INSERT INTO "iana_records" VALUES(3507,0,NULL,'kwz','kwadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3508,0,NULL,'kxa','kairiru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3509,0,NULL,'kxb','krobu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3510,0,NULL,'kxc','khonso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3510,0,NULL,'kxc','konso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3511,0,NULL,'kxd','brunei','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3512,0,NULL,'kxe','kakihum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3513,0,NULL,'kxf','manumanaw karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3514,0,NULL,'kxh','karo (ethiopia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3515,0,NULL,'kxi','keningau murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3516,0,NULL,'kxj','kulfa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3517,0,NULL,'kxk','zayein karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3518,0,NULL,'kxl','nepali kurux','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3519,0,NULL,'kxm','northern khmer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3520,0,NULL,'kxn','kanowit-tanjong melanau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3521,0,NULL,'kxo','kanoé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3522,0,NULL,'kxp','wadiyara koli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3523,0,NULL,'kxq','smärky kanum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3524,0,NULL,'kxr','koro (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3525,0,NULL,'kxs','kangjia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3526,0,NULL,'kxt','koiwat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3527,0,NULL,'kxu','kui (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3528,0,NULL,'kxv','kuvi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3529,0,NULL,'kxw','konai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3530,0,NULL,'kxx','likuba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3531,0,NULL,'kxy','kayong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3532,0,NULL,'kxz','kerewo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3533,0,NULL,'kya','kwaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3534,0,NULL,'kyb','butbut kalinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3535,0,NULL,'kyc','kyaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3536,0,NULL,'kyd','karey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3537,0,NULL,'kye','krache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3538,0,NULL,'kyf','kouya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3539,0,NULL,'kyg','keyagana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3540,0,NULL,'kyh','karok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3541,0,NULL,'kyi','kiput','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3542,0,NULL,'kyj','karao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3543,0,NULL,'kyk','kamayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3544,0,NULL,'kyl','kalapuya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3545,0,NULL,'kym','kpatili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3546,0,NULL,'kyn','northern binukidnon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3547,0,NULL,'kyo','kelon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3548,0,NULL,'kyp','kang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3549,0,NULL,'kyq','kenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3550,0,NULL,'kyr','kuruáya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3551,0,NULL,'kys','baram kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3552,0,NULL,'kyt','kayagar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3553,0,NULL,'kyu','western kayah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3554,0,NULL,'kyv','kayort','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3555,0,NULL,'kyw','kudmali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3556,0,NULL,'kyx','rapoisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3557,0,NULL,'kyy','kambaira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3558,0,NULL,'kyz','kayabí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3559,0,NULL,'kza','western karaboro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3560,0,NULL,'kzb','kaibobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3561,0,NULL,'kzc','bondoukou kulango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3562,0,NULL,'kzd','kadai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3563,0,NULL,'kze','kosena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3564,0,NULL,'kzf','da''a kaili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3565,0,NULL,'kzg','kikai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3566,0,NULL,'kzh','kenuzi-dongola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3567,0,NULL,'kzi','kelabit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3568,0,NULL,'kzj','coastal kadazan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3569,0,NULL,'kzk','kazukuru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3570,0,NULL,'kzl','kayeli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3571,0,NULL,'kzm','kais','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3572,0,NULL,'kzn','kokola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3573,0,NULL,'kzo','kaningi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3574,0,NULL,'kzp','kaidipang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3575,0,NULL,'kzq','kaike','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3576,0,NULL,'kzr','karang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3577,0,NULL,'kzs','sugut dusun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3578,0,NULL,'kzt','tambunan dusun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3579,0,NULL,'kzu','kayupulau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3580,0,NULL,'kzv','komyandaret','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3581,0,NULL,'kzw','karirí-xocó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3582,0,NULL,'kzx','kamarian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3583,0,NULL,'kzy','kango (tshopo district)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3584,0,NULL,'kzz','kalabra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3585,0,NULL,'laa','southern subanen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3586,0,NULL,'lab','linear a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3587,0,NULL,'lac','lacandon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3588,0,NULL,'lad','ladino','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3589,0,NULL,'lae','pattani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3590,0,NULL,'laf','lafofa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3591,0,NULL,'lag','langi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3592,0,NULL,'lah','lahnda','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3593,0,NULL,'lai','lambya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3594,0,NULL,'laj','lango (uganda)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3595,0,NULL,'lak','laka (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3596,0,NULL,'lal','lalia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3597,0,NULL,'lam','lamba','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3598,0,NULL,'lan','laru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3599,0,NULL,'lap','laka (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3600,0,NULL,'laq','qabiao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3601,0,NULL,'lar','larteh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3602,0,NULL,'las','lama (togo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3603,0,NULL,'lau','laba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3604,0,NULL,'law','lauje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3605,0,NULL,'lax','tiwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3606,0,NULL,'lay','lama (myanmar)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3607,0,NULL,'laz','aribwatsa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3608,0,NULL,'lba','lui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3609,0,NULL,'lbb','label','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3610,0,NULL,'lbc','lakkia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3611,0,NULL,'lbe','lak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3612,0,NULL,'lbf','tinani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3613,0,NULL,'lbg','laopang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3614,0,NULL,'lbi','la''bi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3615,0,NULL,'lbj','ladakhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3616,0,NULL,'lbk','central bontok','1268265600',NULL,NULL,NULL,NULL,'bnc',NULL,NULL); +INSERT INTO "iana_records" VALUES(3617,0,NULL,'lbl','libon bikol','1268265600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(3618,0,NULL,'lbm','lodhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3619,0,NULL,'lbn','lamet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3620,0,NULL,'lbo','laven','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3621,0,NULL,'lbq','wampar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3622,0,NULL,'lbr','northern lorung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3623,0,NULL,'lbs','libyan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3624,0,NULL,'lbt','lachi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3625,0,NULL,'lbu','labu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3626,0,NULL,'lbv','lavatbura-lamusong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3627,0,NULL,'lbw','tolaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3628,0,NULL,'lbx','lawangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3629,0,NULL,'lby','lamu-lamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3630,0,NULL,'lbz','lardil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3631,0,NULL,'lcc','legenyem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3632,0,NULL,'lcd','lola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3633,0,NULL,'lce','loncong','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3634,0,NULL,'lcf','lubu','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3635,0,NULL,'lch','luchazi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3636,0,NULL,'lcl','lisela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3637,0,NULL,'lcm','tungag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3638,0,NULL,'lcp','western lawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3639,0,NULL,'lcq','luhu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3640,0,NULL,'lcs','lisabata-nuniali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3641,0,NULL,'ldb','idun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3642,0,NULL,'ldd','luri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3643,0,NULL,'ldg','lenyima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3644,0,NULL,'ldh','lamja-dengsa-tola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3645,0,NULL,'ldi','laari','1248825600',NULL,NULL,NULL,NULL,'kg',NULL,NULL); +INSERT INTO "iana_records" VALUES(3646,0,NULL,'ldj','lemoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3647,0,NULL,'ldk','leelau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3648,0,NULL,'ldl','kaan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3649,0,NULL,'ldm','landoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3650,0,NULL,'ldn','láadan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3651,0,NULL,'ldo','loo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3652,0,NULL,'ldp','tso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3653,0,NULL,'ldq','lufu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3654,0,NULL,'lea','lega-shabunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3655,0,NULL,'leb','lala-bisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3656,0,NULL,'lec','leco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3657,0,NULL,'led','lendu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3658,0,NULL,'lee','lyélé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3659,0,NULL,'lef','lelemi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3660,0,NULL,'leg','lengua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3661,0,NULL,'leh','lenje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3662,0,NULL,'lei','lemio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3663,0,NULL,'lej','lengola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3664,0,NULL,'lek','leipon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3665,0,NULL,'lel','lele (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3666,0,NULL,'lem','nomaande','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3667,0,NULL,'len','lenca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3668,0,NULL,'leo','leti (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3669,0,NULL,'lep','lepcha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3670,0,NULL,'leq','lembena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3671,0,NULL,'ler','lenkau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3672,0,NULL,'les','lese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3673,0,NULL,'let','lesing-gelimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3674,0,NULL,'leu','kara (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3675,0,NULL,'lev','lamma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3676,0,NULL,'lew','ledo kaili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3677,0,NULL,'lex','luang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3678,0,NULL,'ley','lemolang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3679,0,NULL,'lez','lezghian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3680,0,NULL,'lfa','lefa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3681,0,NULL,'lfn','lingua franca nova','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3682,0,NULL,'lga','lungga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3683,0,NULL,'lgb','laghu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3684,0,NULL,'lgg','lugbara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3685,0,NULL,'lgh','laghuu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3686,0,NULL,'lgi','lengilu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3687,0,NULL,'lgk','lingarak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3687,0,NULL,'lgk','neverver','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3688,0,NULL,'lgl','wala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3689,0,NULL,'lgm','lega-mwenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3690,0,NULL,'lgn','opuuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3691,0,NULL,'lgq','logba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3692,0,NULL,'lgr','lengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3693,0,NULL,'lgt','pahi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3694,0,NULL,'lgu','longgu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3695,0,NULL,'lgz','ligenza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3696,0,NULL,'lha','laha (viet nam)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3697,0,NULL,'lhh','laha (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3698,0,NULL,'lhi','lahu shi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3699,0,NULL,'lhl','lahul lohar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3700,0,NULL,'lhm','lhomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3701,0,NULL,'lhn','lahanan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3702,0,NULL,'lhp','lhokpu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3703,0,NULL,'lhs','mlahsö','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3704,0,NULL,'lht','lo-toga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3705,0,NULL,'lhu','lahu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3706,0,NULL,'lia','west-central limba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3707,0,NULL,'lib','likum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3708,0,NULL,'lic','hlai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3709,0,NULL,'lid','nyindrou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3710,0,NULL,'lie','likila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3711,0,NULL,'lif','limbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3712,0,NULL,'lig','ligbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3713,0,NULL,'lih','lihir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3714,0,NULL,'lii','lingkhim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3715,0,NULL,'lij','ligurian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3716,0,NULL,'lik','lika','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3717,0,NULL,'lil','lillooet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3718,0,NULL,'lio','liki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3719,0,NULL,'lip','sekpele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3720,0,NULL,'liq','libido','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3721,0,NULL,'lir','liberian english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3722,0,NULL,'lis','lisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3723,0,NULL,'liu','logorik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3724,0,NULL,'liv','liv','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3725,0,NULL,'liw','col','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3726,0,NULL,'lix','liabuku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3727,0,NULL,'liy','banda-bambari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3728,0,NULL,'liz','libinza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3729,0,NULL,'lje','rampi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3730,0,NULL,'lji','laiyolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3731,0,NULL,'ljl','li''o','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3732,0,NULL,'ljp','lampung api','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3733,0,NULL,'lka','lakalei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3734,0,NULL,'lkb','kabras','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3734,0,NULL,'lkb','lukabaras','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3735,0,NULL,'lkc','kucong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3736,0,NULL,'lkd','lakondê','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3737,0,NULL,'lke','kenyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3738,0,NULL,'lkh','lakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3739,0,NULL,'lki','laki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3740,0,NULL,'lkj','remun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3741,0,NULL,'lkl','laeko-libuat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3742,0,NULL,'lkn','lakon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3742,0,NULL,'lkn','vure','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3743,0,NULL,'lko','khayo','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3743,0,NULL,'lko','olukhayo','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3744,0,NULL,'lkr','päri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3745,0,NULL,'lks','kisa','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3745,0,NULL,'lks','olushisa','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3746,0,NULL,'lkt','lakota','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3747,0,NULL,'lky','lokoya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3748,0,NULL,'lla','lala-roba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3749,0,NULL,'llb','lolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3750,0,NULL,'llc','lele (guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3751,0,NULL,'lld','ladin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3752,0,NULL,'lle','lele (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3753,0,NULL,'llf','hermit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3754,0,NULL,'llg','lole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3755,0,NULL,'llh','lamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3756,0,NULL,'lli','teke-laali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3757,0,NULL,'llk','lelak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3758,0,NULL,'lll','lilau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3759,0,NULL,'llm','lasalimu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3760,0,NULL,'lln','lele (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3761,0,NULL,'llo','khlor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3762,0,NULL,'llp','north efate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3763,0,NULL,'llq','lolak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3764,0,NULL,'lls','lithuanian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3765,0,NULL,'llu','lau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3766,0,NULL,'llx','lauan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3767,0,NULL,'lma','east limba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3768,0,NULL,'lmb','merei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3769,0,NULL,'lmc','limilngan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3770,0,NULL,'lmd','lumun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3771,0,NULL,'lme','pévé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3772,0,NULL,'lmf','south lembata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3773,0,NULL,'lmg','lamogai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3774,0,NULL,'lmh','lambichhong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3775,0,NULL,'lmi','lombi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3776,0,NULL,'lmj','west lembata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3777,0,NULL,'lmk','lamkang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3778,0,NULL,'lml','hano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3779,0,NULL,'lmm','lamam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3780,0,NULL,'lmn','lambadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3781,0,NULL,'lmo','lombard','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3782,0,NULL,'lmp','limbum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3783,0,NULL,'lmq','lamatuka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3784,0,NULL,'lmr','lamalera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3785,0,NULL,'lmu','lamenu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3786,0,NULL,'lmv','lomaiviti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3787,0,NULL,'lmw','lake miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3788,0,NULL,'lmx','laimbue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3789,0,NULL,'lmy','lamboya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3790,0,NULL,'lmz','lumbee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3791,0,NULL,'lna','langbashe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3792,0,NULL,'lnb','mbalanhu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3793,0,NULL,'lnd','lun bawang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3793,0,NULL,'lnd','lundayeh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3794,0,NULL,'lng','langobardic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3795,0,NULL,'lnh','lanoh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3796,0,NULL,'lni','daantanai''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3797,0,NULL,'lnj','leningitij','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3798,0,NULL,'lnl','south central banda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3799,0,NULL,'lnm','langam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3800,0,NULL,'lnn','lorediakarkar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3801,0,NULL,'lno','lango (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3802,0,NULL,'lns','lamnso''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3803,0,NULL,'lnu','longuda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3804,0,NULL,'lnz','lonzo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3805,0,NULL,'loa','loloda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3806,0,NULL,'lob','lobi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3807,0,NULL,'loc','inonhan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3808,0,NULL,'loe','saluan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3809,0,NULL,'lof','logol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3810,0,NULL,'log','logo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3811,0,NULL,'loh','narim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3812,0,NULL,'loi','loma (côte d''ivoire)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3813,0,NULL,'loj','lou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3814,0,NULL,'lok','loko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3815,0,NULL,'lol','mongo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3816,0,NULL,'lom','loma (liberia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3817,0,NULL,'lon','malawi lomwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3818,0,NULL,'loo','lombo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3819,0,NULL,'lop','lopa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3820,0,NULL,'loq','lobala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3821,0,NULL,'lor','téén','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3822,0,NULL,'los','loniu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3823,0,NULL,'lot','otuho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3824,0,NULL,'lou','louisiana creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3825,0,NULL,'lov','lopi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3826,0,NULL,'low','tampias lobu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3827,0,NULL,'lox','loun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3828,0,NULL,'loy','lowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3829,0,NULL,'loz','lozi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3830,0,NULL,'lpa','lelepa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3831,0,NULL,'lpe','lepki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3832,0,NULL,'lpn','long phuri naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3833,0,NULL,'lpo','lipo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3834,0,NULL,'lpx','lopit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3835,0,NULL,'lra','rara bakati''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3836,0,NULL,'lrc','northern luri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3837,0,NULL,'lre','laurentian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3838,0,NULL,'lrg','laragia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3839,0,NULL,'lri','marachi','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3839,0,NULL,'lri','olumarachi','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3840,0,NULL,'lrk','loarki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3841,0,NULL,'lrl','lari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3842,0,NULL,'lrm','marama','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3842,0,NULL,'lrm','olumarama','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3843,0,NULL,'lrn','lorang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3844,0,NULL,'lro','laro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3845,0,NULL,'lrr','southern lorung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3846,0,NULL,'lrt','larantuka malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3847,0,NULL,'lrv','larevat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3848,0,NULL,'lrz','lemerig','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3849,0,NULL,'lsa','lasgerdi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3850,0,NULL,'lsd','lishana deni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3851,0,NULL,'lse','lusengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3852,0,NULL,'lsg','lyons sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3853,0,NULL,'lsh','lish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3854,0,NULL,'lsi','lashi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3855,0,NULL,'lsl','latvian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3856,0,NULL,'lsm','olusamia','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3856,0,NULL,'lsm','saamia','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3857,0,NULL,'lso','laos sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3858,0,NULL,'lsp','lengua de señas panameñas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3858,0,NULL,'lsp','panamanian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3859,0,NULL,'lsr','aruop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3860,0,NULL,'lss','lasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3861,0,NULL,'lst','trinidad and tobago sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3862,0,NULL,'lsy','mauritian sign language','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3863,0,NULL,'ltc','late middle chinese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3864,0,NULL,'ltg','latgalian','1268265600',NULL,NULL,NULL,NULL,'lv',NULL,NULL); +INSERT INTO "iana_records" VALUES(3865,0,NULL,'lti','leti (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3866,0,NULL,'ltn','latundê','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3867,0,NULL,'lto','olutsotso','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3867,0,NULL,'lto','tsotso','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3868,0,NULL,'lts','lutachoni','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3868,0,NULL,'lts','tachoni','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3869,0,NULL,'ltu','latu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3870,0,NULL,'lua','luba-lulua','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3871,0,NULL,'luc','aringa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3872,0,NULL,'lud','ludian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3873,0,NULL,'lue','luvale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3874,0,NULL,'luf','laua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3875,0,NULL,'lui','luiseno','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3876,0,NULL,'luj','luna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3877,0,NULL,'luk','lunanakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3878,0,NULL,'lul','olu''bo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3879,0,NULL,'lum','luimbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3880,0,NULL,'lun','lunda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3881,0,NULL,'luo','dholuo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3881,0,NULL,'luo','luo (kenya and tanzania)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3882,0,NULL,'lup','lumbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3883,0,NULL,'luq','lucumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3884,0,NULL,'lur','laura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3885,0,NULL,'lus','lushai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3886,0,NULL,'lut','lushootseed','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3887,0,NULL,'luu','lumba-yakkha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3888,0,NULL,'luv','luwati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3889,0,NULL,'luw','luo (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3890,0,NULL,'luy','luyia','1248825600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3890,0,NULL,'luy','oluluyia','1248825600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3891,0,NULL,'luz','southern luri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3892,0,NULL,'lva','maku''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3893,0,NULL,'lvk','lavukaleve','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3894,0,NULL,'lvs','standard latvian','1268265600',NULL,NULL,NULL,NULL,'lv',NULL,NULL); +INSERT INTO "iana_records" VALUES(3895,0,NULL,'lvu','levuka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3896,0,NULL,'lwa','lwalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3897,0,NULL,'lwe','lewo eleng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3898,0,NULL,'lwg','oluwanga','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3898,0,NULL,'lwg','wanga','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(3899,0,NULL,'lwh','white lachi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3900,0,NULL,'lwl','eastern lawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3901,0,NULL,'lwm','laomian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3902,0,NULL,'lwo','luwo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3903,0,NULL,'lwt','lewotobi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3904,0,NULL,'lww','lewo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3905,0,NULL,'lya','layakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3906,0,NULL,'lyg','lyngngam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3907,0,NULL,'lyn','luyana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3908,0,NULL,'lzh','literary chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(3909,0,NULL,'lzl','litzlitz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3910,0,NULL,'lzn','leinong naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3911,0,NULL,'lzz','laz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3912,0,NULL,'maa','san jerónimo tecóatl mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3913,0,NULL,'mab','yutanduchi mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3914,0,NULL,'mad','madurese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3915,0,NULL,'mae','bo-rukul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3916,0,NULL,'maf','mafa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3917,0,NULL,'mag','magahi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3918,0,NULL,'mai','maithili','1129420800',NULL,NULL,NULL,'deva',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3919,0,NULL,'maj','jalapa de díaz mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3920,0,NULL,'mak','makasar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3921,0,NULL,'mam','mam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3922,0,NULL,'man','mandingo','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(3923,0,NULL,'map','austronesian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(3924,0,NULL,'maq','chiquihuitlán mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3925,0,NULL,'mas','masai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3926,0,NULL,'mat','san francisco matlatzinca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3927,0,NULL,'mau','huautla mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3928,0,NULL,'mav','sateré-mawé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3929,0,NULL,'maw','mampruli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3930,0,NULL,'max','north moluccan malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(3931,0,NULL,'maz','central mazahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3932,0,NULL,'mba','higaonon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3933,0,NULL,'mbb','western bukidnon manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3934,0,NULL,'mbc','macushi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3935,0,NULL,'mbd','dibabawon manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3936,0,NULL,'mbe','molale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3937,0,NULL,'mbf','baba malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3938,0,NULL,'mbh','mangseng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3939,0,NULL,'mbi','ilianen manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3940,0,NULL,'mbj','nadëb','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3941,0,NULL,'mbk','malol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3942,0,NULL,'mbl','maxakalí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3943,0,NULL,'mbm','ombamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3944,0,NULL,'mbn','macaguán','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3945,0,NULL,'mbo','mbo (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3946,0,NULL,'mbp','malayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3947,0,NULL,'mbq','maisin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3948,0,NULL,'mbr','nukak makú','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3949,0,NULL,'mbs','sarangani manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3950,0,NULL,'mbt','matigsalug manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3951,0,NULL,'mbu','mbula-bwazza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3952,0,NULL,'mbv','mbulungish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3953,0,NULL,'mbw','maring','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3954,0,NULL,'mbx','mari (east sepik province)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3955,0,NULL,'mby','memoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3956,0,NULL,'mbz','amoltepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3957,0,NULL,'mca','maca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3958,0,NULL,'mcb','machiguenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3959,0,NULL,'mcc','bitur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3960,0,NULL,'mcd','sharanahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3961,0,NULL,'mce','itundujia mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3962,0,NULL,'mcf','matsés','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3963,0,NULL,'mcg','mapoyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3964,0,NULL,'mch','maquiritari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3965,0,NULL,'mci','mese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3966,0,NULL,'mcj','mvanip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3967,0,NULL,'mck','mbunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3968,0,NULL,'mcl','macaguaje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3969,0,NULL,'mcm','malaccan creole portuguese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3970,0,NULL,'mcn','masana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3971,0,NULL,'mco','coatlán mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3972,0,NULL,'mcp','makaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3973,0,NULL,'mcq','ese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3974,0,NULL,'mcr','menya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3975,0,NULL,'mcs','mambai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3976,0,NULL,'mct','mengisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3977,0,NULL,'mcu','cameroon mambila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3978,0,NULL,'mcv','minanibai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3979,0,NULL,'mcw','mawa (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3980,0,NULL,'mcx','mpiemo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3981,0,NULL,'mcy','south watut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3982,0,NULL,'mcz','mawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3983,0,NULL,'mda','mada (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3984,0,NULL,'mdb','morigi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3985,0,NULL,'mdc','male (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3986,0,NULL,'mdd','mbum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3987,0,NULL,'mde','maba (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3988,0,NULL,'mdf','moksha','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3989,0,NULL,'mdg','massalat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3990,0,NULL,'mdh','maguindanaon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3991,0,NULL,'mdi','mamvu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3992,0,NULL,'mdj','mangbetu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3993,0,NULL,'mdk','mangbutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3994,0,NULL,'mdl','maltese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3995,0,NULL,'mdm','mayogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3996,0,NULL,'mdn','mbati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3997,0,NULL,'mdp','mbala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3998,0,NULL,'mdq','mbole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(3999,0,NULL,'mdr','mandar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4000,0,NULL,'mds','maria (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4001,0,NULL,'mdt','mbere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4002,0,NULL,'mdu','mboko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4003,0,NULL,'mdv','santa lucía monteverde mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4004,0,NULL,'mdw','mbosi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4005,0,NULL,'mdx','dizin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4006,0,NULL,'mdy','male (ethiopia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4007,0,NULL,'mdz','suruí do pará','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4008,0,NULL,'mea','menka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4009,0,NULL,'meb','ikobi-mena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4010,0,NULL,'mec','mara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4011,0,NULL,'med','melpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4012,0,NULL,'mee','mengen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4013,0,NULL,'mef','megam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4014,0,NULL,'meg','mea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4015,0,NULL,'meh','southwestern tlaxiaco mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4016,0,NULL,'mei','midob','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4017,0,NULL,'mej','meyah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4018,0,NULL,'mek','mekeo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4019,0,NULL,'mel','central melanau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4020,0,NULL,'mem','mangala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4021,0,NULL,'men','mende (sierra leone)','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4022,0,NULL,'meo','kedah malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4023,0,NULL,'mep','miriwung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4024,0,NULL,'meq','merey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4025,0,NULL,'mer','meru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4026,0,NULL,'mes','masmaje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4027,0,NULL,'met','mato','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4028,0,NULL,'meu','motu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4029,0,NULL,'mev','mann','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4030,0,NULL,'mew','maaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4031,0,NULL,'mey','hassaniyya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4032,0,NULL,'mez','menominee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4033,0,NULL,'mfa','pattani malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4034,0,NULL,'mfb','bangka','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4035,0,NULL,'mfc','mba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4036,0,NULL,'mfd','mendankwe-nkwen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4037,0,NULL,'mfe','morisyen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4038,0,NULL,'mff','naki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4039,0,NULL,'mfg','mixifore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4040,0,NULL,'mfh','matal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4041,0,NULL,'mfi','wandala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4042,0,NULL,'mfj','mefele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4043,0,NULL,'mfk','north mofu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4044,0,NULL,'mfl','putai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4045,0,NULL,'mfm','marghi south','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4046,0,NULL,'mfn','cross river mbembe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4047,0,NULL,'mfo','mbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4048,0,NULL,'mfp','makassar malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4049,0,NULL,'mfq','moba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4050,0,NULL,'mfr','marithiel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4051,0,NULL,'mfs','mexican sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4052,0,NULL,'mft','mokerang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4053,0,NULL,'mfu','mbwela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4054,0,NULL,'mfv','mandjak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4055,0,NULL,'mfw','mulaha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4056,0,NULL,'mfx','melo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4057,0,NULL,'mfy','mayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4058,0,NULL,'mfz','mabaan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4059,0,NULL,'mga','middle irish (900-1200)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4060,0,NULL,'mgb','mararit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4061,0,NULL,'mgc','morokodo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4062,0,NULL,'mgd','moru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4063,0,NULL,'mge','mango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4064,0,NULL,'mgf','maklew','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4065,0,NULL,'mgg','mpongmpong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4066,0,NULL,'mgh','makhuwa-meetto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4067,0,NULL,'mgi','lijili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4068,0,NULL,'mgj','abureni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4069,0,NULL,'mgk','mawes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4070,0,NULL,'mgl','maleu-kilenge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4071,0,NULL,'mgm','mambae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4072,0,NULL,'mgn','mbangi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4073,0,NULL,'mgo','meta''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4074,0,NULL,'mgp','eastern magar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4075,0,NULL,'mgq','malila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4076,0,NULL,'mgr','mambwe-lungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4077,0,NULL,'mgs','manda (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4078,0,NULL,'mgt','mongol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4079,0,NULL,'mgu','mailu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4080,0,NULL,'mgv','matengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4081,0,NULL,'mgw','matumbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4082,0,NULL,'mgx','omati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4083,0,NULL,'mgy','mbunga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4084,0,NULL,'mgz','mbugwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4085,0,NULL,'mha','manda (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4086,0,NULL,'mhb','mahongwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4087,0,NULL,'mhc','mocho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4088,0,NULL,'mhd','mbugu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4089,0,NULL,'mhe','besisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4089,0,NULL,'mhe','mah meri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4090,0,NULL,'mhf','mamaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4091,0,NULL,'mhg','margu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4092,0,NULL,'mhh','maskoy pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4093,0,NULL,'mhi','ma''di','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4094,0,NULL,'mhj','mogholi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4095,0,NULL,'mhk','mungaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4096,0,NULL,'mhl','mauwake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4097,0,NULL,'mhm','makhuwa-moniga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4098,0,NULL,'mhn','mócheno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4099,0,NULL,'mho','mashi (zambia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4100,0,NULL,'mhp','balinese malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4101,0,NULL,'mhq','mandan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4102,0,NULL,'mhr','eastern mari','1248825600',NULL,NULL,NULL,NULL,'chm',NULL,NULL); +INSERT INTO "iana_records" VALUES(4103,0,NULL,'mhs','buru (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4104,0,NULL,'mht','mandahuaca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4105,0,NULL,'mhu','darang deng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4105,0,NULL,'mhu','digaro-mishmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4106,0,NULL,'mhw','mbukushu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4107,0,NULL,'mhx','lhaovo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4107,0,NULL,'mhx','maru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4108,0,NULL,'mhy','ma''anyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4109,0,NULL,'mhz','mor (mor islands)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4110,0,NULL,'mia','miami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4111,0,NULL,'mib','atatláhuca mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4112,0,NULL,'mic','mi''kmaq','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4112,0,NULL,'mic','micmac','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4113,0,NULL,'mid','mandaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4114,0,NULL,'mie','ocotepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4115,0,NULL,'mif','mofu-gudur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4116,0,NULL,'mig','san miguel el grande mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4117,0,NULL,'mih','chayuco mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4118,0,NULL,'mii','chigmecatitlán mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4119,0,NULL,'mij','abar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4120,0,NULL,'mik','mikasuki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4121,0,NULL,'mil','peñoles mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4122,0,NULL,'mim','alacatlatzala mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4123,0,NULL,'min','minangkabau','1129420800',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4124,0,NULL,'mio','pinotepa nacional mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4125,0,NULL,'mip','apasco-apoala mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4126,0,NULL,'miq','mískito','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4127,0,NULL,'mir','isthmus mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4128,0,NULL,'mis','uncoded languages','1129420800',NULL,NULL,NULL,NULL,NULL,'special',NULL); +INSERT INTO "iana_records" VALUES(4129,0,NULL,'mit','southern puebla mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4130,0,NULL,'miu','cacaloxtepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4131,0,NULL,'miw','akoye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4132,0,NULL,'mix','mixtepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4133,0,NULL,'miy','ayutla mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4134,0,NULL,'miz','coatzospan mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4135,0,NULL,'mja','mahei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4136,0,NULL,'mjc','san juan colorado mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4137,0,NULL,'mjd','northwest maidu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4138,0,NULL,'mje','muskum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4139,0,NULL,'mjg','tu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4140,0,NULL,'mjh','mwera (nyasa)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4141,0,NULL,'mji','kim mun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4142,0,NULL,'mjj','mawak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4143,0,NULL,'mjk','matukar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4144,0,NULL,'mjl','mandeali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4145,0,NULL,'mjm','medebur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4146,0,NULL,'mjn','ma (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4147,0,NULL,'mjo','malankuravan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4148,0,NULL,'mjp','malapandaram','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4149,0,NULL,'mjq','malaryan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4150,0,NULL,'mjr','malavedan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4151,0,NULL,'mjs','miship','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4152,0,NULL,'mjt','sauria paharia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4153,0,NULL,'mju','manna-dora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4154,0,NULL,'mjv','mannan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4155,0,NULL,'mjw','karbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4156,0,NULL,'mjx','mahali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4157,0,NULL,'mjy','mahican','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4158,0,NULL,'mjz','majhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4159,0,NULL,'mka','mbre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4160,0,NULL,'mkb','mal paharia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4161,0,NULL,'mkc','siliput','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4162,0,NULL,'mke','mawchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4163,0,NULL,'mkf','miya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4164,0,NULL,'mkg','mak (china)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4165,0,NULL,'mkh','mon-khmer languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4166,0,NULL,'mki','dhatki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4167,0,NULL,'mkj','mokilese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4168,0,NULL,'mkk','byep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4169,0,NULL,'mkl','mokole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4170,0,NULL,'mkm','moklen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4171,0,NULL,'mkn','kupang malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4172,0,NULL,'mko','mingang doso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4173,0,NULL,'mkp','moikodi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4174,0,NULL,'mkq','bay miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4175,0,NULL,'mkr','malas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4176,0,NULL,'mks','silacayoapan mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4177,0,NULL,'mkt','vamale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4178,0,NULL,'mku','konyanka maninka','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4179,0,NULL,'mkv','mafea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4180,0,NULL,'mkw','kituba (congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4181,0,NULL,'mkx','kinamiging manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4182,0,NULL,'mky','east makian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4183,0,NULL,'mkz','makasae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4184,0,NULL,'mla','malo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4185,0,NULL,'mlb','mbule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4186,0,NULL,'mlc','cao lan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4187,0,NULL,'mld','malakhel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4188,0,NULL,'mle','manambu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4189,0,NULL,'mlf','mal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4190,0,NULL,'mlh','mape','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4191,0,NULL,'mli','malimpung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4192,0,NULL,'mlj','miltu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4193,0,NULL,'mlk','ilwana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4193,0,NULL,'mlk','kiwilwana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4194,0,NULL,'mll','malua bay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4195,0,NULL,'mlm','mulam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4196,0,NULL,'mln','malango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4197,0,NULL,'mlo','mlomp','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4198,0,NULL,'mlp','bargam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4199,0,NULL,'mlq','western maninkakan','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4200,0,NULL,'mlr','vame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4201,0,NULL,'mls','masalit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4202,0,NULL,'mlu','to''abaita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4203,0,NULL,'mlv','motlav','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4203,0,NULL,'mlv','mwotlap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4204,0,NULL,'mlw','moloko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4205,0,NULL,'mlx','malfaxal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4205,0,NULL,'mlx','naha''ai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4206,0,NULL,'mlz','malaynon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4207,0,NULL,'mma','mama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4208,0,NULL,'mmb','momina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4209,0,NULL,'mmc','michoacán mazahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4210,0,NULL,'mmd','maonan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4211,0,NULL,'mme','mae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4212,0,NULL,'mmf','mundat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4213,0,NULL,'mmg','north ambrym','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4214,0,NULL,'mmh','mehináku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4215,0,NULL,'mmi','musar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4216,0,NULL,'mmj','majhwar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4217,0,NULL,'mmk','mukha-dora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4218,0,NULL,'mml','man met','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4219,0,NULL,'mmm','maii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4220,0,NULL,'mmn','mamanwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4221,0,NULL,'mmo','mangga buang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4222,0,NULL,'mmp','siawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4223,0,NULL,'mmq','musak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4224,0,NULL,'mmr','western xiangxi miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4225,0,NULL,'mmt','malalamai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4226,0,NULL,'mmu','mmaala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4227,0,NULL,'mmv','miriti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4228,0,NULL,'mmw','emae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4229,0,NULL,'mmx','madak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4230,0,NULL,'mmy','migaama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4231,0,NULL,'mmz','mabaale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4232,0,NULL,'mna','mbula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4233,0,NULL,'mnb','muna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4234,0,NULL,'mnc','manchu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4235,0,NULL,'mnd','mondé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4236,0,NULL,'mne','naba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4237,0,NULL,'mnf','mundani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4238,0,NULL,'mng','eastern mnong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4239,0,NULL,'mnh','mono (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4240,0,NULL,'mni','manipuri','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4241,0,NULL,'mnj','munji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4242,0,NULL,'mnk','mandinka','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4243,0,NULL,'mnl','tiale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4244,0,NULL,'mnm','mapena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4245,0,NULL,'mnn','southern mnong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4246,0,NULL,'mno','manobo languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4247,0,NULL,'mnp','min bei chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(4248,0,NULL,'mnq','minriq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4249,0,NULL,'mnr','mono (usa)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4250,0,NULL,'mns','mansi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4251,0,NULL,'mnt','maykulan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4252,0,NULL,'mnu','mer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4253,0,NULL,'mnv','rennell-bellona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4254,0,NULL,'mnw','mon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4255,0,NULL,'mnx','manikion','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4256,0,NULL,'mny','manyawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4257,0,NULL,'mnz','moni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4258,0,NULL,'moa','mwan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4259,0,NULL,'moc','mocoví','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4260,0,NULL,'mod','mobilian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4261,0,NULL,'moe','montagnais','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4262,0,NULL,'mof','mohegan-montauk-narragansett','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see xnt, xpq'); +INSERT INTO "iana_records" VALUES(4263,0,NULL,'mog','mongondow','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4264,0,NULL,'moh','mohawk','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4265,0,NULL,'moi','mboi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4266,0,NULL,'moj','monzombo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4267,0,NULL,'mok','morori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4268,0,NULL,'mom','mangue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4269,0,NULL,'moo','monom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4270,0,NULL,'mop','mopán maya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4271,0,NULL,'moq','mor (bomberai peninsula)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4272,0,NULL,'mor','moro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4273,0,NULL,'mos','mossi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4274,0,NULL,'mot','barí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4275,0,NULL,'mou','mogum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4276,0,NULL,'mov','mohave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4277,0,NULL,'mow','moi (congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4278,0,NULL,'mox','molima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4279,0,NULL,'moy','shekkacho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4280,0,NULL,'moz','mukulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4281,0,NULL,'mpa','mpoto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4282,0,NULL,'mpb','mullukmulluk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4283,0,NULL,'mpc','mangarayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4284,0,NULL,'mpd','machinere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4285,0,NULL,'mpe','majang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4286,0,NULL,'mpg','marba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4287,0,NULL,'mph','maung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4288,0,NULL,'mpi','mpade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4289,0,NULL,'mpj','martu wangka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4290,0,NULL,'mpk','mbara (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4291,0,NULL,'mpl','middle watut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4292,0,NULL,'mpm','yosondúa mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4293,0,NULL,'mpn','mindiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4294,0,NULL,'mpo','miu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4295,0,NULL,'mpp','migabac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4296,0,NULL,'mpq','matís','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4297,0,NULL,'mpr','vangunu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4298,0,NULL,'mps','dadibi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4299,0,NULL,'mpt','mian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4300,0,NULL,'mpu','makuráp','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4301,0,NULL,'mpv','mungkip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4302,0,NULL,'mpw','mapidian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4303,0,NULL,'mpx','misima-paneati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4304,0,NULL,'mpy','mapia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4305,0,NULL,'mpz','mpi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4306,0,NULL,'mqa','maba (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4307,0,NULL,'mqb','mbuko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4308,0,NULL,'mqc','mangole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4309,0,NULL,'mqe','matepi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4310,0,NULL,'mqf','momuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4311,0,NULL,'mqg','kota bangun kutai malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4312,0,NULL,'mqh','tlazoyaltepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4313,0,NULL,'mqi','mariri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4314,0,NULL,'mqj','mamasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4315,0,NULL,'mqk','rajah kabunsuwan manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4316,0,NULL,'mql','mbelime','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4317,0,NULL,'mqm','south marquesan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4318,0,NULL,'mqn','moronene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4319,0,NULL,'mqo','modole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4320,0,NULL,'mqp','manipa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4321,0,NULL,'mqq','minokok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4322,0,NULL,'mqr','mander','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4323,0,NULL,'mqs','west makian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4324,0,NULL,'mqt','mok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4325,0,NULL,'mqu','mandari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4326,0,NULL,'mqv','mosimo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4327,0,NULL,'mqw','murupi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4328,0,NULL,'mqx','mamuju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4329,0,NULL,'mqy','manggarai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4330,0,NULL,'mqz','malasanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4331,0,NULL,'mra','mlabri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4332,0,NULL,'mrb','marino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4333,0,NULL,'mrc','maricopa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4334,0,NULL,'mrd','western magar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4335,0,NULL,'mre','martha''s vineyard sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4336,0,NULL,'mrf','elseng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4337,0,NULL,'mrg','miri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4338,0,NULL,'mrh','mara chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4339,0,NULL,'mrj','western mari','1248825600',NULL,NULL,NULL,NULL,'chm',NULL,NULL); +INSERT INTO "iana_records" VALUES(4340,0,NULL,'mrk','hmwaveke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4341,0,NULL,'mrl','mortlockese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4342,0,NULL,'mrm','merlav','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4342,0,NULL,'mrm','mwerlap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4343,0,NULL,'mrn','cheke holo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4344,0,NULL,'mro','mru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4345,0,NULL,'mrp','morouas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4346,0,NULL,'mrq','north marquesan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4347,0,NULL,'mrr','maria (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4348,0,NULL,'mrs','maragus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4349,0,NULL,'mrt','marghi central','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4350,0,NULL,'mru','mono (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4351,0,NULL,'mrv','mangareva','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4352,0,NULL,'mrw','maranao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4353,0,NULL,'mrx','dineor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4353,0,NULL,'mrx','maremgi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4354,0,NULL,'mry','mandaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4355,0,NULL,'mrz','marind','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4356,0,NULL,'msb','masbatenyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4357,0,NULL,'msc','sankaran maninka','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4358,0,NULL,'msd','yucatec maya sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4359,0,NULL,'mse','musey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4360,0,NULL,'msf','mekwei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4361,0,NULL,'msg','moraid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4362,0,NULL,'msh','masikoro malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(4363,0,NULL,'msi','sabah malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4364,0,NULL,'msj','ma (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4365,0,NULL,'msk','mansaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4366,0,NULL,'msl','molof','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4366,0,NULL,'msl','poule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4367,0,NULL,'msm','agusan manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4368,0,NULL,'msn','vurës','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4369,0,NULL,'mso','mombum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4370,0,NULL,'msp','maritsauá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4371,0,NULL,'msq','caac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4372,0,NULL,'msr','mongolian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4373,0,NULL,'mss','west masela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4374,0,NULL,'mst','cataelano mandaya','1248825600',1268265600,'mry',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4375,0,NULL,'msu','musom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4376,0,NULL,'msv','maslam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4377,0,NULL,'msw','mansoanka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4378,0,NULL,'msx','moresada','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4379,0,NULL,'msy','aruamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4380,0,NULL,'msz','momare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4381,0,NULL,'mta','cotabato manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4382,0,NULL,'mtb','anyin morofo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4383,0,NULL,'mtc','munit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4384,0,NULL,'mtd','mualang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4385,0,NULL,'mte','mono (solomon islands)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4386,0,NULL,'mtf','murik (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4387,0,NULL,'mtg','una','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4388,0,NULL,'mth','munggui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4389,0,NULL,'mti','maiwa (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4390,0,NULL,'mtj','moskona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4391,0,NULL,'mtk','mbe''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4392,0,NULL,'mtl','montol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4393,0,NULL,'mtm','mator','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4394,0,NULL,'mtn','matagalpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4395,0,NULL,'mto','totontepec mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4396,0,NULL,'mtp','wichí lhamtés nocten','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4397,0,NULL,'mtq','muong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4398,0,NULL,'mtr','mewari','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(4399,0,NULL,'mts','yora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4400,0,NULL,'mtt','mota','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4401,0,NULL,'mtu','tututepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4402,0,NULL,'mtv','asaro''o','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4403,0,NULL,'mtw','southern binukidnon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4404,0,NULL,'mtx','tidaá mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4405,0,NULL,'mty','nabi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4406,0,NULL,'mua','mundang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4407,0,NULL,'mub','mubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4408,0,NULL,'muc','mbu''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4409,0,NULL,'mud','mednyj aleut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4410,0,NULL,'mue','media lengua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4411,0,NULL,'mug','musgu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4412,0,NULL,'muh','mündü','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4413,0,NULL,'mui','musi','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(4414,0,NULL,'muj','mabire','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4415,0,NULL,'muk','mugom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4416,0,NULL,'mul','multiple languages','1129420800',NULL,NULL,NULL,NULL,NULL,'special',NULL); +INSERT INTO "iana_records" VALUES(4417,0,NULL,'mum','maiwala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4418,0,NULL,'mun','munda languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4419,0,NULL,'muo','nyong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4420,0,NULL,'mup','malvi','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(4421,0,NULL,'muq','eastern xiangxi miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4422,0,NULL,'mur','murle','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4423,0,NULL,'mus','creek','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4424,0,NULL,'mut','western muria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4425,0,NULL,'muu','yaaku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4426,0,NULL,'muv','muthuvan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4427,0,NULL,'mux','bo-ung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4428,0,NULL,'muy','muyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4429,0,NULL,'muz','mursi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4430,0,NULL,'mva','manam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4431,0,NULL,'mvb','mattole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4432,0,NULL,'mvd','mamboru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4433,0,NULL,'mve','marwari (pakistan)','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(4434,0,NULL,'mvf','peripheral mongolian','1248825600',NULL,NULL,NULL,NULL,'mn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4435,0,NULL,'mvg','yucuañe mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4436,0,NULL,'mvh','mire','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4437,0,NULL,'mvi','miyako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4438,0,NULL,'mvk','mekmek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4439,0,NULL,'mvl','mbara (australia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4440,0,NULL,'mvm','muya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4441,0,NULL,'mvn','minaveha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4442,0,NULL,'mvo','marovo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4443,0,NULL,'mvp','duri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4444,0,NULL,'mvq','moere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4445,0,NULL,'mvr','marau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4446,0,NULL,'mvs','massep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4447,0,NULL,'mvt','mpotovoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4448,0,NULL,'mvu','marfa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4449,0,NULL,'mvv','tagal murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4450,0,NULL,'mvw','machinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4451,0,NULL,'mvx','meoswar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4452,0,NULL,'mvy','indus kohistani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4453,0,NULL,'mvz','mesqan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4454,0,NULL,'mwa','mwatebu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4455,0,NULL,'mwb','juwal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4456,0,NULL,'mwc','are','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4457,0,NULL,'mwd','mudbura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4458,0,NULL,'mwe','mwera (chimwera)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4459,0,NULL,'mwf','murrinh-patha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4460,0,NULL,'mwg','aiklep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4461,0,NULL,'mwh','mouk-aria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4462,0,NULL,'mwi','labo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4462,0,NULL,'mwi','ninde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4463,0,NULL,'mwj','maligo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4464,0,NULL,'mwk','kita maninkakan','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4465,0,NULL,'mwl','mirandese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4466,0,NULL,'mwm','sar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4467,0,NULL,'mwn','nyamwanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4468,0,NULL,'mwo','central maewo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4469,0,NULL,'mwp','kala lagaw ya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4470,0,NULL,'mwq','mün chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4471,0,NULL,'mwr','marwari','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(4472,0,NULL,'mws','mwimbi-muthambi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4473,0,NULL,'mwt','moken','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4474,0,NULL,'mwu','mittu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4475,0,NULL,'mwv','mentawai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4476,0,NULL,'mww','hmong daw','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4477,0,NULL,'mwx','mediak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4478,0,NULL,'mwy','mosiro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4479,0,NULL,'mwz','moingi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4480,0,NULL,'mxa','northwest oaxaca mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4481,0,NULL,'mxb','tezoatlán mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4482,0,NULL,'mxc','manyika','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4483,0,NULL,'mxd','modang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4484,0,NULL,'mxe','mele-fila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4485,0,NULL,'mxf','malgbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4486,0,NULL,'mxg','mbangala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4487,0,NULL,'mxh','mvuba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4488,0,NULL,'mxi','mozarabic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4489,0,NULL,'mxj','geman deng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4489,0,NULL,'mxj','miju-mishmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4490,0,NULL,'mxk','monumbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4491,0,NULL,'mxl','maxi gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4492,0,NULL,'mxm','meramera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4493,0,NULL,'mxn','moi (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4494,0,NULL,'mxo','mbowe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4495,0,NULL,'mxp','tlahuitoltepec mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4496,0,NULL,'mxq','juquila mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4497,0,NULL,'mxr','murik (malaysia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4498,0,NULL,'mxs','huitepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4499,0,NULL,'mxt','jamiltepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4500,0,NULL,'mxu','mada (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4501,0,NULL,'mxv','metlatónoc mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4502,0,NULL,'mxw','namo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4503,0,NULL,'mxx','mahou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4503,0,NULL,'mxx','mawukakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4504,0,NULL,'mxy','southeastern nochixtlán mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4505,0,NULL,'mxz','central masela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4506,0,NULL,'myb','mbay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4507,0,NULL,'myc','mayeka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4508,0,NULL,'myd','maramba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4509,0,NULL,'mye','myene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4510,0,NULL,'myf','bambassi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4511,0,NULL,'myg','manta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4512,0,NULL,'myh','makah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4513,0,NULL,'myi','mina (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4514,0,NULL,'myj','mangayat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4515,0,NULL,'myk','mamara senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4516,0,NULL,'myl','moma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4517,0,NULL,'mym','me''en','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4518,0,NULL,'myn','mayan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4519,0,NULL,'myo','anfillo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4520,0,NULL,'myp','pirahã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4521,0,NULL,'myq','forest maninka','1248825600',NULL,NULL,NULL,NULL,'man',NULL,NULL); +INSERT INTO "iana_records" VALUES(4522,0,NULL,'myr','muniche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4523,0,NULL,'mys','mesmes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4524,0,NULL,'myt','sangab mandaya','1248825600',1268265600,'mry',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4525,0,NULL,'myu','mundurukú','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4526,0,NULL,'myv','erzya','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4527,0,NULL,'myw','muyuw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4528,0,NULL,'myx','masaaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4529,0,NULL,'myy','macuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4530,0,NULL,'myz','classical mandaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4531,0,NULL,'mza','santa maría zacatepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4532,0,NULL,'mzb','tumzabt','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4533,0,NULL,'mzc','madagascar sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4534,0,NULL,'mzd','malimba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4535,0,NULL,'mze','morawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4536,0,NULL,'mzg','monastic sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4537,0,NULL,'mzh','wichí lhamtés güisnay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4538,0,NULL,'mzi','ixcatlán mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4539,0,NULL,'mzj','manya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4540,0,NULL,'mzk','nigeria mambila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4541,0,NULL,'mzl','mazatlán mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4542,0,NULL,'mzm','mumuye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4543,0,NULL,'mzn','mazanderani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4544,0,NULL,'mzo','matipuhy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4545,0,NULL,'mzp','movima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4546,0,NULL,'mzq','mori atas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4547,0,NULL,'mzr','marúbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4548,0,NULL,'mzs','macanese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4549,0,NULL,'mzt','mintil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4550,0,NULL,'mzu','inapang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4551,0,NULL,'mzv','manza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4552,0,NULL,'mzw','deg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4553,0,NULL,'mzx','mawayana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4554,0,NULL,'mzy','mozambican sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4555,0,NULL,'mzz','maiadomu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4556,0,NULL,'naa','namla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4557,0,NULL,'nab','southern nambikuára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4558,0,NULL,'nac','narak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4559,0,NULL,'nad','nijadali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4560,0,NULL,'nae','naka''ela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4561,0,NULL,'naf','nabak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4562,0,NULL,'nag','naga pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4563,0,NULL,'nah','nahuatl languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4564,0,NULL,'nai','north american indian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4565,0,NULL,'naj','nalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4566,0,NULL,'nak','nakanai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4567,0,NULL,'nal','nalik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4568,0,NULL,'nam','nangikurrunggurr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4569,0,NULL,'nan','min nan chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(4570,0,NULL,'nao','naaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4571,0,NULL,'nap','neapolitan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4572,0,NULL,'naq','nama (namibia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4573,0,NULL,'nar','iguta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4574,0,NULL,'nas','naasioi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4575,0,NULL,'nat','hungworo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4576,0,NULL,'naw','nawuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4577,0,NULL,'nax','nakwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4578,0,NULL,'nay','narrinyeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4579,0,NULL,'naz','coatepec nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4580,0,NULL,'nba','nyemba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4581,0,NULL,'nbb','ndoe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4582,0,NULL,'nbc','chang naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4583,0,NULL,'nbd','ngbinda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4584,0,NULL,'nbe','konyak naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4585,0,NULL,'nbf','naxi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4586,0,NULL,'nbg','nagarchal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4587,0,NULL,'nbh','ngamo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4588,0,NULL,'nbi','mao naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4589,0,NULL,'nbj','ngarinman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4590,0,NULL,'nbk','nake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4591,0,NULL,'nbm','ngbaka ma''bo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4592,0,NULL,'nbn','kuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4593,0,NULL,'nbo','nkukoli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4594,0,NULL,'nbp','nnam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4595,0,NULL,'nbq','nggem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4596,0,NULL,'nbr','numana-nunku-gbantu-numbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4597,0,NULL,'nbs','namibian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4598,0,NULL,'nbt','na','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4599,0,NULL,'nbu','rongmei naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4600,0,NULL,'nbv','ngamambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4601,0,NULL,'nbw','southern ngbandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4602,0,NULL,'nbx','ngura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4603,0,NULL,'nby','ningera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4604,0,NULL,'nca','iyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4605,0,NULL,'ncb','central nicobarese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4606,0,NULL,'ncc','ponam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4607,0,NULL,'ncd','nachering','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4608,0,NULL,'nce','yale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4609,0,NULL,'ncf','notsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4610,0,NULL,'ncg','nisga''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4611,0,NULL,'nch','central huasteca nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4612,0,NULL,'nci','classical nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4613,0,NULL,'ncj','northern puebla nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4614,0,NULL,'nck','nakara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4615,0,NULL,'ncl','michoacán nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4616,0,NULL,'ncm','nambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4617,0,NULL,'ncn','nauna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4618,0,NULL,'nco','sibe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4619,0,NULL,'ncp','ndaktup','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4620,0,NULL,'ncr','ncane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4621,0,NULL,'ncs','nicaraguan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4622,0,NULL,'nct','chothe naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4623,0,NULL,'ncu','chumburung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4624,0,NULL,'ncx','central puebla nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4625,0,NULL,'ncz','natchez','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4626,0,NULL,'nda','ndasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4627,0,NULL,'ndb','kenswei nsei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4628,0,NULL,'ndc','ndau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4629,0,NULL,'ndd','nde-nsele-nta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4630,0,NULL,'ndf','nadruvian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4631,0,NULL,'ndg','ndengereko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4632,0,NULL,'ndh','ndali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4633,0,NULL,'ndi','samba leko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4634,0,NULL,'ndj','ndamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4635,0,NULL,'ndk','ndaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4636,0,NULL,'ndl','ndolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4637,0,NULL,'ndm','ndam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4638,0,NULL,'ndn','ngundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4639,0,NULL,'ndp','ndo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4640,0,NULL,'ndq','ndombe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4641,0,NULL,'ndr','ndoola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4642,0,NULL,'nds','low german','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4642,0,NULL,'nds','low saxon','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4643,0,NULL,'ndt','ndunga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4644,0,NULL,'ndu','dugun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4645,0,NULL,'ndv','ndut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4646,0,NULL,'ndw','ndobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4647,0,NULL,'ndx','nduga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4648,0,NULL,'ndy','lutos','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4649,0,NULL,'ndz','ndogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4650,0,NULL,'nea','eastern ngad''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4651,0,NULL,'neb','toura (côte d''ivoire)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4652,0,NULL,'nec','nedebang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4653,0,NULL,'ned','nde-gbite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4654,0,NULL,'nee','kumak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4655,0,NULL,'nef','nefamese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4656,0,NULL,'neg','negidal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4657,0,NULL,'neh','nyenkha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4658,0,NULL,'nei','neo-hittite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4659,0,NULL,'nej','neko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4660,0,NULL,'nek','neku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4661,0,NULL,'nem','nemi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4662,0,NULL,'nen','nengone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4663,0,NULL,'neo','ná-meo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4664,0,NULL,'neq','north central mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4665,0,NULL,'ner','yahadian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4666,0,NULL,'nes','bhoti kinnauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4667,0,NULL,'net','nete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4668,0,NULL,'nev','nyaheun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4669,0,NULL,'new','nepal bhasa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4669,0,NULL,'new','newari','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4670,0,NULL,'nex','neme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4671,0,NULL,'ney','neyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4672,0,NULL,'nez','nez perce','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4673,0,NULL,'nfa','dhao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4674,0,NULL,'nfd','ahwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4675,0,NULL,'nfl','ayiwo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4675,0,NULL,'nfl','Äiwoo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4676,0,NULL,'nfr','nafaanra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4677,0,NULL,'nfu','mfumte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4678,0,NULL,'nga','ngbaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4679,0,NULL,'ngb','northern ngbandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4680,0,NULL,'ngc','ngombe (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4681,0,NULL,'ngd','ngando (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4682,0,NULL,'nge','ngemba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4683,0,NULL,'ngf','trans-new guinea languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4684,0,NULL,'ngg','ngbaka manza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4685,0,NULL,'ngh','n/u','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4686,0,NULL,'ngi','ngizim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4687,0,NULL,'ngj','ngie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4688,0,NULL,'ngk','ngalkbun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4689,0,NULL,'ngl','lomwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4690,0,NULL,'ngm','ngatik men''s creole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4691,0,NULL,'ngn','ngwo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4692,0,NULL,'ngo','ngoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4693,0,NULL,'ngp','ngulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4694,0,NULL,'ngq','ngoreme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4694,0,NULL,'ngq','ngurimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4695,0,NULL,'ngr','nagu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4695,0,NULL,'ngr','nanggu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4696,0,NULL,'ngs','gvoko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4697,0,NULL,'ngt','ngeq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4698,0,NULL,'ngu','guerrero nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4699,0,NULL,'ngv','nagumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4700,0,NULL,'ngw','ngwaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4701,0,NULL,'ngx','nggwahyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4702,0,NULL,'ngy','tibea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4703,0,NULL,'ngz','ngungwel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4704,0,NULL,'nha','nhanda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4705,0,NULL,'nhb','beng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4706,0,NULL,'nhc','tabasco nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4707,0,NULL,'nhd','ava guaraní','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4707,0,NULL,'nhd','chiripá','1248825600',NULL,NULL,NULL,NULL,'gn',NULL,NULL); +INSERT INTO "iana_records" VALUES(4708,0,NULL,'nhe','eastern huasteca nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4709,0,NULL,'nhf','nhuwala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4710,0,NULL,'nhg','tetelcingo nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4711,0,NULL,'nhh','nahari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4712,0,NULL,'nhi','zacatlán-ahuacatlán-tepetzintla nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4713,0,NULL,'nhk','isthmus-cosoleacaque nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4714,0,NULL,'nhm','morelos nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4715,0,NULL,'nhn','central nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4716,0,NULL,'nho','takuu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4717,0,NULL,'nhp','isthmus-pajapan nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4718,0,NULL,'nhq','huaxcaleca nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4719,0,NULL,'nhr','naro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4720,0,NULL,'nht','ometepec nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4721,0,NULL,'nhu','noone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4722,0,NULL,'nhv','temascaltepec nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4723,0,NULL,'nhw','western huasteca nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4724,0,NULL,'nhx','isthmus-mecayapan nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4725,0,NULL,'nhy','northern oaxaca nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4726,0,NULL,'nhz','santa maría la alta nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4727,0,NULL,'nia','nias','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4728,0,NULL,'nib','nakama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4729,0,NULL,'nic','niger-kordofanian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4730,0,NULL,'nid','ngandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4731,0,NULL,'nie','niellim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4732,0,NULL,'nif','nek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4733,0,NULL,'nig','ngalakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4734,0,NULL,'nih','nyiha (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4735,0,NULL,'nii','nii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4736,0,NULL,'nij','ngaju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4737,0,NULL,'nik','southern nicobarese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4738,0,NULL,'nil','nila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4739,0,NULL,'nim','nilamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4740,0,NULL,'nin','ninzo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4741,0,NULL,'nio','nganasan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4742,0,NULL,'niq','nandi','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(4743,0,NULL,'nir','nimboran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4744,0,NULL,'nis','nimi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4745,0,NULL,'nit','southeastern kolami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4746,0,NULL,'niu','niuean','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4747,0,NULL,'niv','gilyak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4748,0,NULL,'niw','nimo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4749,0,NULL,'nix','hema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4750,0,NULL,'niy','ngiti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4751,0,NULL,'niz','ningil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4752,0,NULL,'nja','nzanyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4753,0,NULL,'njb','nocte naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4754,0,NULL,'njd','ndonde hamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4755,0,NULL,'njh','lotha naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4756,0,NULL,'nji','gudanji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4757,0,NULL,'njj','njen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4758,0,NULL,'njl','njalgulgule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4759,0,NULL,'njm','angami naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4760,0,NULL,'njn','liangmai naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4761,0,NULL,'njo','ao naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4762,0,NULL,'njr','njerep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4763,0,NULL,'njs','nisa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4764,0,NULL,'njt','ndyuka-trio pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4765,0,NULL,'nju','ngadjunmaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4766,0,NULL,'njx','kunyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4767,0,NULL,'njy','njyem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4768,0,NULL,'nka','nkoya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4769,0,NULL,'nkb','khoibu naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4770,0,NULL,'nkc','nkongho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4771,0,NULL,'nkd','koireng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4772,0,NULL,'nke','duke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4773,0,NULL,'nkf','inpui naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4774,0,NULL,'nkg','nekgini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4775,0,NULL,'nkh','khezha naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4776,0,NULL,'nki','thangal naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4777,0,NULL,'nkj','nakai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4778,0,NULL,'nkk','nokuku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4779,0,NULL,'nkm','namat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4780,0,NULL,'nkn','nkangala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4781,0,NULL,'nko','nkonya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4782,0,NULL,'nkp','niuatoputapu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4783,0,NULL,'nkq','nkami','1271376000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4784,0,NULL,'nkr','nukuoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4785,0,NULL,'nks','north asmat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4786,0,NULL,'nkt','nyika (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4787,0,NULL,'nku','bouna kulango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4788,0,NULL,'nkv','nyika (malawi and zambia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4789,0,NULL,'nkw','nkutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4790,0,NULL,'nkx','nkoroo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4791,0,NULL,'nkz','nkari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4792,0,NULL,'nla','ngombale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4793,0,NULL,'nlc','nalca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4794,0,NULL,'nle','east nyala','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(4795,0,NULL,'nlg','gela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4796,0,NULL,'nli','grangali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4797,0,NULL,'nlj','nyali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4798,0,NULL,'nlk','ninia yali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4799,0,NULL,'nll','nihali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4800,0,NULL,'nln','durango nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4801,0,NULL,'nlo','ngul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4802,0,NULL,'nlr','ngarla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4803,0,NULL,'nlu','nchumbulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4804,0,NULL,'nlv','orizaba nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4805,0,NULL,'nlx','nahali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4806,0,NULL,'nly','nyamal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4807,0,NULL,'nlz','nalögo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4808,0,NULL,'nma','maram naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4809,0,NULL,'nmb','big nambas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4809,0,NULL,'nmb','v''ënen taut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4810,0,NULL,'nmc','ngam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4811,0,NULL,'nmd','ndumu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4812,0,NULL,'nme','mzieme naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4813,0,NULL,'nmf','tangkhul naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4814,0,NULL,'nmg','kwasio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4815,0,NULL,'nmh','monsang naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4816,0,NULL,'nmi','nyam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4817,0,NULL,'nmj','ngombe (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4818,0,NULL,'nmk','namakura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4819,0,NULL,'nml','ndemli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4820,0,NULL,'nmm','manangba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4821,0,NULL,'nmn','!xóõ','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4822,0,NULL,'nmo','moyon naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4823,0,NULL,'nmp','nimanbur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4824,0,NULL,'nmq','nambya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4825,0,NULL,'nmr','nimbari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4826,0,NULL,'nms','letemboi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4827,0,NULL,'nmt','namonuito','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4828,0,NULL,'nmu','northeast maidu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4829,0,NULL,'nmv','ngamini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4830,0,NULL,'nmw','nimoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4831,0,NULL,'nmx','nama (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4832,0,NULL,'nmy','namuyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4833,0,NULL,'nmz','nawdm','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4834,0,NULL,'nna','nyangumarta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4835,0,NULL,'nnb','nande','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4836,0,NULL,'nnc','nancere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4837,0,NULL,'nnd','west ambae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4838,0,NULL,'nne','ngandyera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4839,0,NULL,'nnf','ngaing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4840,0,NULL,'nng','maring naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4841,0,NULL,'nnh','ngiemboon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4842,0,NULL,'nni','north nuaulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4843,0,NULL,'nnj','nyangatom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4844,0,NULL,'nnk','nankina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4845,0,NULL,'nnl','northern rengma naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4846,0,NULL,'nnm','namia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4847,0,NULL,'nnn','ngete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4848,0,NULL,'nnp','wancho naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4849,0,NULL,'nnq','ngindo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4850,0,NULL,'nnr','narungga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4851,0,NULL,'nns','ningye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4852,0,NULL,'nnt','nanticoke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4853,0,NULL,'nnu','dwang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4854,0,NULL,'nnv','nugunu (australia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4855,0,NULL,'nnw','southern nuni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4856,0,NULL,'nnx','ngong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4857,0,NULL,'nny','nyangga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4858,0,NULL,'nnz','nda''nda''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4859,0,NULL,'noa','woun meu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4860,0,NULL,'noc','nuk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4861,0,NULL,'nod','northern thai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4862,0,NULL,'noe','nimadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4863,0,NULL,'nof','nomane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4864,0,NULL,'nog','nogai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4865,0,NULL,'noh','nomu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4866,0,NULL,'noi','noiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4867,0,NULL,'noj','nonuya','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4868,0,NULL,'nok','nooksack','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4869,0,NULL,'nom','nocamán','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4870,0,NULL,'non','old norse','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4871,0,NULL,'noo','nootka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4872,0,NULL,'nop','numanggang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4873,0,NULL,'noq','ngongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4874,0,NULL,'nos','eastern nisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4875,0,NULL,'not','nomatsiguenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4876,0,NULL,'nou','ewage-notu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4877,0,NULL,'nov','novial','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4878,0,NULL,'now','nyambo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4879,0,NULL,'noy','noy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4880,0,NULL,'noz','nayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4881,0,NULL,'npa','nar phu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4882,0,NULL,'npb','nupbikha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4883,0,NULL,'nph','phom naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4884,0,NULL,'npl','southeastern puebla nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4885,0,NULL,'npn','mondropolon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4886,0,NULL,'npo','pochuri naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4887,0,NULL,'nps','nipsan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4888,0,NULL,'npu','puimei naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4889,0,NULL,'npy','napu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4890,0,NULL,'nqg','southern nago','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4891,0,NULL,'nqk','kura ede nago','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4892,0,NULL,'nqm','ndom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4893,0,NULL,'nqn','nen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4894,0,NULL,'nqo','n''ko','1149465600',NULL,NULL,NULL,'nkoo',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4894,0,NULL,'nqo','n’ko','1149465600',NULL,NULL,NULL,'nkoo',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4895,0,NULL,'nra','ngom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4896,0,NULL,'nrb','nara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4897,0,NULL,'nrc','noric','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4898,0,NULL,'nre','southern rengma naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4899,0,NULL,'nrg','narango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4900,0,NULL,'nri','chokri naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4901,0,NULL,'nrl','ngarluma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4902,0,NULL,'nrm','narom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4903,0,NULL,'nrn','norn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4904,0,NULL,'nrp','north picene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4905,0,NULL,'nrr','norra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4906,0,NULL,'nrt','northern kalapuya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4907,0,NULL,'nrx','ngurmbur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4908,0,NULL,'nrz','lala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4909,0,NULL,'nsa','sangtam naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4910,0,NULL,'nsc','nshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4911,0,NULL,'nsd','southern nisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4912,0,NULL,'nse','nsenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4913,0,NULL,'nsg','ngasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4914,0,NULL,'nsh','ngoshie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4915,0,NULL,'nsi','nigerian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4916,0,NULL,'nsk','naskapi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4917,0,NULL,'nsl','norwegian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4918,0,NULL,'nsm','sumi naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4919,0,NULL,'nsn','nehan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4920,0,NULL,'nso','northern sotho','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4920,0,NULL,'nso','pedi','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4920,0,NULL,'nso','sepedi','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4921,0,NULL,'nsp','nepalese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4922,0,NULL,'nsq','northern sierra miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4923,0,NULL,'nsr','maritime sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4924,0,NULL,'nss','nali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4925,0,NULL,'nst','tase naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4926,0,NULL,'nsu','sierra negra nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4927,0,NULL,'nsv','southwestern nisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4928,0,NULL,'nsw','navut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4929,0,NULL,'nsx','nsongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4930,0,NULL,'nsy','nasal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4931,0,NULL,'nsz','nisenan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4932,0,NULL,'nte','nathembo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4933,0,NULL,'nti','natioro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4934,0,NULL,'ntj','ngaanyatjarra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4935,0,NULL,'ntk','ikoma-nata-isenye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4936,0,NULL,'ntm','nateni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4937,0,NULL,'nto','ntomba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4938,0,NULL,'ntp','northern tepehuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4939,0,NULL,'ntr','delo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4940,0,NULL,'nts','natagaimas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4941,0,NULL,'ntu','natügu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4942,0,NULL,'ntw','nottoway','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4943,0,NULL,'nty','mantsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4944,0,NULL,'ntz','natanzi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4945,0,NULL,'nua','yuaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4946,0,NULL,'nub','nubian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(4947,0,NULL,'nuc','nukuini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4948,0,NULL,'nud','ngala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4949,0,NULL,'nue','ngundu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4950,0,NULL,'nuf','nusu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4951,0,NULL,'nug','nungali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4952,0,NULL,'nuh','ndunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4953,0,NULL,'nui','ngumbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4954,0,NULL,'nuj','nyole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4955,0,NULL,'nul','nusa laut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4956,0,NULL,'num','niuafo''ou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4957,0,NULL,'nun','nung (myanmar)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4958,0,NULL,'nuo','nguôn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4959,0,NULL,'nup','nupe-nupe-tako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4960,0,NULL,'nuq','nukumanu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4961,0,NULL,'nur','nukuria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4962,0,NULL,'nus','nuer','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4963,0,NULL,'nut','nung (viet nam)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4964,0,NULL,'nuu','ngbundu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4965,0,NULL,'nuv','northern nuni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4966,0,NULL,'nuw','nguluwan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4967,0,NULL,'nux','mehek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4968,0,NULL,'nuy','nunggubuyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4969,0,NULL,'nuz','tlamacazapa nahuatl','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4970,0,NULL,'nvh','nasarian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4971,0,NULL,'nvm','namiae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4972,0,NULL,'nwa','nawathinehena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4973,0,NULL,'nwb','nyabwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4974,0,NULL,'nwc','classical nepal bhasa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4974,0,NULL,'nwc','classical newari','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4974,0,NULL,'nwc','old newari','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4975,0,NULL,'nwe','ngwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4976,0,NULL,'nwi','southwest tanna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4977,0,NULL,'nwm','nyamusa-molo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4978,0,NULL,'nwr','nawaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4979,0,NULL,'nwx','middle newar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4980,0,NULL,'nwy','nottoway-meherrin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4981,0,NULL,'nxa','nauete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4982,0,NULL,'nxd','ngando (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4983,0,NULL,'nxe','nage','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4984,0,NULL,'nxg','ngad''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4985,0,NULL,'nxi','nindi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4986,0,NULL,'nxl','south nuaulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4987,0,NULL,'nxm','numidian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4988,0,NULL,'nxn','ngawun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4989,0,NULL,'nxr','ninggerum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4990,0,NULL,'nxu','narau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4991,0,NULL,'nxx','nafri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4992,0,NULL,'nyb','nyangbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4993,0,NULL,'nyc','nyanga-li','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4994,0,NULL,'nyd','nyore','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(4994,0,NULL,'nyd','olunyole','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(4995,0,NULL,'nye','nyengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4996,0,NULL,'nyf','giryama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4996,0,NULL,'nyf','kigiryama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4997,0,NULL,'nyg','nyindu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4998,0,NULL,'nyh','nyigina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(4999,0,NULL,'nyi','ama (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5000,0,NULL,'nyj','nyanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5001,0,NULL,'nyk','nyaneka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5002,0,NULL,'nyl','nyeu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5003,0,NULL,'nym','nyamwezi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5004,0,NULL,'nyn','nyankole','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5005,0,NULL,'nyo','nyoro','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5006,0,NULL,'nyp','nyang''i','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5007,0,NULL,'nyq','nayini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5008,0,NULL,'nyr','nyiha (malawi)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5009,0,NULL,'nys','nyunga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5010,0,NULL,'nyt','nyawaygi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5011,0,NULL,'nyu','nyungwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5012,0,NULL,'nyv','nyulnyul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5013,0,NULL,'nyw','nyaw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5014,0,NULL,'nyx','nganyaywana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5015,0,NULL,'nyy','nyakyusa-ngonde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5016,0,NULL,'nza','tigon mbembe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5017,0,NULL,'nzb','njebi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5018,0,NULL,'nzi','nzima','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5019,0,NULL,'nzk','nzakara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5020,0,NULL,'nzm','zeme naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5021,0,NULL,'nzs','new zealand sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5022,0,NULL,'nzu','teke-nzikou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5023,0,NULL,'nzy','nzakambay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5024,0,NULL,'nzz','nanga dama dogon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5025,0,NULL,'oaa','orok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5026,0,NULL,'oac','oroch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5027,0,NULL,'oar','ancient aramaic (up to 700 bce)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5027,0,NULL,'oar','old aramaic (up to 700 bce)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5028,0,NULL,'oav','old avar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5029,0,NULL,'obi','obispeño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5030,0,NULL,'obk','southern bontok','1268265600',NULL,NULL,NULL,NULL,'bnc',NULL,NULL); +INSERT INTO "iana_records" VALUES(5031,0,NULL,'obl','oblo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5032,0,NULL,'obm','moabite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5033,0,NULL,'obo','obo manobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5034,0,NULL,'obr','old burmese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5035,0,NULL,'obt','old breton','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5036,0,NULL,'obu','obulom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5037,0,NULL,'oca','ocaina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5038,0,NULL,'och','old chinese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5039,0,NULL,'oco','old cornish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5040,0,NULL,'ocu','atzingo matlatzinca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5041,0,NULL,'oda','odut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5042,0,NULL,'odk','od','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5043,0,NULL,'odt','old dutch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5044,0,NULL,'odu','odual','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5045,0,NULL,'ofo','ofo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5046,0,NULL,'ofs','old frisian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5047,0,NULL,'ofu','efutop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5048,0,NULL,'ogb','ogbia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5049,0,NULL,'ogc','ogbah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5050,0,NULL,'oge','old georgian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5051,0,NULL,'ogg','ogbogolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5052,0,NULL,'ogo','khana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5053,0,NULL,'ogu','ogbronuagum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5054,0,NULL,'oht','old hittite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5055,0,NULL,'ohu','old hungarian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5056,0,NULL,'oia','oirata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5057,0,NULL,'oin','inebu one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5058,0,NULL,'ojb','northwestern ojibwa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5059,0,NULL,'ojc','central ojibwa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5060,0,NULL,'ojg','eastern ojibwa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5061,0,NULL,'ojp','old japanese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5062,0,NULL,'ojs','severn ojibwa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5063,0,NULL,'ojv','ontong java','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5064,0,NULL,'ojw','western ojibwa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5065,0,NULL,'oka','okanagan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5066,0,NULL,'okb','okobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5067,0,NULL,'okd','okodia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5068,0,NULL,'oke','okpe (southwestern edo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5069,0,NULL,'okh','koresh-e rostam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5070,0,NULL,'oki','okiek','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(5071,0,NULL,'okj','oko-juwoi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5072,0,NULL,'okk','kwamtim one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5073,0,NULL,'okl','old kentish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5074,0,NULL,'okm','middle korean (10th-16th cent.)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5075,0,NULL,'okn','oki-no-erabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5076,0,NULL,'oko','old korean (3rd-9th cent.)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5077,0,NULL,'okr','kirike','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5078,0,NULL,'oks','oko-eni-osayen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5079,0,NULL,'oku','oku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5080,0,NULL,'okv','orokaiva','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5081,0,NULL,'okx','okpe (northwestern edo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5082,0,NULL,'ola','walungge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5083,0,NULL,'old','mochi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5084,0,NULL,'ole','olekha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5085,0,NULL,'olm','oloma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5086,0,NULL,'olo','livvi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5087,0,NULL,'olr','olrat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5088,0,NULL,'oma','omaha-ponca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5089,0,NULL,'omb','east ambae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5090,0,NULL,'omc','mochica','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5091,0,NULL,'ome','omejes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5092,0,NULL,'omg','omagua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5093,0,NULL,'omi','omi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5094,0,NULL,'omk','omok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5095,0,NULL,'oml','ombo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5096,0,NULL,'omn','minoan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5097,0,NULL,'omo','utarmbung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5098,0,NULL,'omp','old manipuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5099,0,NULL,'omq','oto-manguean languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5100,0,NULL,'omr','old marathi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5101,0,NULL,'omt','omotik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5102,0,NULL,'omu','omurano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5103,0,NULL,'omv','omotic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5104,0,NULL,'omw','south tairora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5105,0,NULL,'omx','old mon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5106,0,NULL,'ona','ona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5107,0,NULL,'onb','lingao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5108,0,NULL,'one','oneida','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5109,0,NULL,'ong','olo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5110,0,NULL,'oni','onin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5111,0,NULL,'onj','onjob','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5112,0,NULL,'onk','kabore one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5113,0,NULL,'onn','onobasulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5114,0,NULL,'ono','onondaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5115,0,NULL,'onp','sartang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5116,0,NULL,'onr','northern one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5117,0,NULL,'ons','ono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5118,0,NULL,'ont','ontenu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5119,0,NULL,'onu','unua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5120,0,NULL,'onw','old nubian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5121,0,NULL,'onx','onin based pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5122,0,NULL,'ood','tohono o''odham','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5123,0,NULL,'oog','ong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5124,0,NULL,'oon','Önge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5125,0,NULL,'oor','oorlams','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5126,0,NULL,'oos','old ossetic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5127,0,NULL,'opa','okpamheri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5128,0,NULL,'opk','kopkaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5129,0,NULL,'opm','oksapmin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5130,0,NULL,'opo','opao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5131,0,NULL,'opt','opata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5132,0,NULL,'opy','ofayé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5133,0,NULL,'ora','oroha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5134,0,NULL,'orc','orma','1248825600',NULL,NULL,NULL,NULL,'om',NULL,NULL); +INSERT INTO "iana_records" VALUES(5135,0,NULL,'ore','orejón','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5136,0,NULL,'org','oring','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5137,0,NULL,'orh','oroqen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5138,0,NULL,'orn','orang kanaq','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(5139,0,NULL,'oro','orokolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5140,0,NULL,'orr','oruma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5141,0,NULL,'ors','orang seletar','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(5142,0,NULL,'ort','adivasi oriya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5143,0,NULL,'oru','ormuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5144,0,NULL,'orv','old russian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5145,0,NULL,'orw','oro win','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5146,0,NULL,'orx','oro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5147,0,NULL,'orz','ormu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5148,0,NULL,'osa','osage','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5149,0,NULL,'osc','oscan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5150,0,NULL,'osi','osing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5151,0,NULL,'oso','ososo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5152,0,NULL,'osp','old spanish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5153,0,NULL,'ost','osatu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5154,0,NULL,'osu','southern one','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5155,0,NULL,'osx','old saxon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5156,0,NULL,'ota','ottoman turkish (1500-1928)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5157,0,NULL,'otb','old tibetan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5158,0,NULL,'otd','ot danum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5159,0,NULL,'ote','mezquital otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5160,0,NULL,'oti','oti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5161,0,NULL,'otk','old turkish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5162,0,NULL,'otl','tilapa otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5163,0,NULL,'otm','eastern highland otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5164,0,NULL,'otn','tenango otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5165,0,NULL,'oto','otomian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5166,0,NULL,'otq','querétaro otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5167,0,NULL,'otr','otoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5168,0,NULL,'ots','estado de méxico otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5169,0,NULL,'ott','temoaya otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5170,0,NULL,'otu','otuke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5171,0,NULL,'otw','ottawa','1248825600',NULL,NULL,NULL,NULL,'oj',NULL,NULL); +INSERT INTO "iana_records" VALUES(5172,0,NULL,'otx','texcatepec otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5173,0,NULL,'oty','old tamil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5174,0,NULL,'otz','ixtenco otomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5175,0,NULL,'oua','tagargrent','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5176,0,NULL,'oub','glio-oubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5177,0,NULL,'oue','ounge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5178,0,NULL,'oui','old uighur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5179,0,NULL,'oum','ouma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5180,0,NULL,'oun','!o!ung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5181,0,NULL,'owi','owiniga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5182,0,NULL,'owl','old welsh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5183,0,NULL,'oyb','oy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5184,0,NULL,'oyd','oyda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5185,0,NULL,'oym','wayampi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5186,0,NULL,'oyy','oya''oya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5187,0,NULL,'ozm','koonzime','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5188,0,NULL,'paa','papuan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5189,0,NULL,'pab','parecís','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5190,0,NULL,'pac','pacoh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5191,0,NULL,'pad','paumarí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5192,0,NULL,'pae','pagibete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5193,0,NULL,'paf','paranawát','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5194,0,NULL,'pag','pangasinan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5195,0,NULL,'pah','tenharim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5196,0,NULL,'pai','pe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5197,0,NULL,'pak','parakanã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5198,0,NULL,'pal','pahlavi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5199,0,NULL,'pam','kapampangan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5199,0,NULL,'pam','pampanga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5200,0,NULL,'pao','northern paiute','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5201,0,NULL,'pap','papiamento','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5202,0,NULL,'paq','parya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5203,0,NULL,'par','panamint','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5203,0,NULL,'par','timbisha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5204,0,NULL,'pas','papasena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5205,0,NULL,'pat','papitalai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5206,0,NULL,'pau','palauan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5207,0,NULL,'pav','pakaásnovos','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5208,0,NULL,'paw','pawnee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5209,0,NULL,'pax','pankararé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5210,0,NULL,'pay','pech','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5211,0,NULL,'paz','pankararú','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5212,0,NULL,'pbb','páez','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5213,0,NULL,'pbc','patamona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5214,0,NULL,'pbe','mezontla popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5215,0,NULL,'pbf','coyotepec popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5216,0,NULL,'pbg','paraujano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5217,0,NULL,'pbh','e''ñapa woromaipu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5218,0,NULL,'pbi','parkwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5219,0,NULL,'pbl','mak (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5220,0,NULL,'pbn','kpasam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5221,0,NULL,'pbo','papel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5222,0,NULL,'pbp','badyara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5223,0,NULL,'pbr','pangwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5224,0,NULL,'pbs','central pame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5225,0,NULL,'pbt','southern pashto','1248825600',NULL,NULL,NULL,NULL,'ps',NULL,NULL); +INSERT INTO "iana_records" VALUES(5226,0,NULL,'pbu','northern pashto','1248825600',NULL,NULL,NULL,NULL,'ps',NULL,NULL); +INSERT INTO "iana_records" VALUES(5227,0,NULL,'pbv','pnar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5228,0,NULL,'pby','pyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5229,0,NULL,'pbz','palu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5230,0,NULL,'pca','santa inés ahuatempan popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5231,0,NULL,'pcb','pear','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5232,0,NULL,'pcc','bouyei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5233,0,NULL,'pcd','picard','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5234,0,NULL,'pce','ruching palaung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5235,0,NULL,'pcf','paliyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5236,0,NULL,'pcg','paniya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5237,0,NULL,'pch','pardhan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5238,0,NULL,'pci','duruwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5239,0,NULL,'pcj','parenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5240,0,NULL,'pck','paite chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5241,0,NULL,'pcl','pardhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5242,0,NULL,'pcm','nigerian pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5243,0,NULL,'pcn','piti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5244,0,NULL,'pcp','pacahuara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5245,0,NULL,'pcr','panang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5246,0,NULL,'pcw','pyapun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5247,0,NULL,'pda','anam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5248,0,NULL,'pdc','pennsylvania german','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5249,0,NULL,'pdi','pa di','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5250,0,NULL,'pdn','fedan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5250,0,NULL,'pdn','podena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5251,0,NULL,'pdo','padoe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5252,0,NULL,'pdt','plautdietsch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5253,0,NULL,'pdu','kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5254,0,NULL,'pea','peranakan indonesian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5255,0,NULL,'peb','eastern pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5256,0,NULL,'ped','mala (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5257,0,NULL,'pee','taje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5258,0,NULL,'pef','northeastern pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5259,0,NULL,'peg','pengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5260,0,NULL,'peh','bonan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5261,0,NULL,'pei','chichimeca-jonaz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5262,0,NULL,'pej','northern pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5263,0,NULL,'pek','penchal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5264,0,NULL,'pel','pekal','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(5265,0,NULL,'pem','phende','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5266,0,NULL,'peo','old persian (ca. 600-400 b.c.)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5267,0,NULL,'pep','kunja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5268,0,NULL,'peq','southern pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5269,0,NULL,'pes','iranian persian','1248825600',NULL,NULL,NULL,NULL,'fa',NULL,NULL); +INSERT INTO "iana_records" VALUES(5270,0,NULL,'pev','pémono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5271,0,NULL,'pex','petats','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5272,0,NULL,'pey','petjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5273,0,NULL,'pez','eastern penan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5274,0,NULL,'pfa','pááfang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5275,0,NULL,'pfe','peere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5276,0,NULL,'pfl','pfaelzisch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5277,0,NULL,'pga','sudanese creole arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(5278,0,NULL,'pgg','pangwali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5279,0,NULL,'pgi','pagi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5280,0,NULL,'pgk','rerep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5281,0,NULL,'pgn','paelignian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5282,0,NULL,'pgs','pangseng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5283,0,NULL,'pgu','pagu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5284,0,NULL,'pgy','pongyong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5285,0,NULL,'pha','pa-hng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5286,0,NULL,'phd','phudagi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5287,0,NULL,'phg','phuong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5288,0,NULL,'phh','phukha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5289,0,NULL,'phi','philippine languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5290,0,NULL,'phk','phake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5291,0,NULL,'phl','palula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5291,0,NULL,'phl','phalura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5292,0,NULL,'phm','phimbi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5293,0,NULL,'phn','phoenician','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5294,0,NULL,'pho','phunoi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5295,0,NULL,'phq','phana''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5296,0,NULL,'phr','pahari-potwari','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(5297,0,NULL,'pht','phu thai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5298,0,NULL,'phu','phuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5299,0,NULL,'phv','pahlavani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5300,0,NULL,'phw','phangduwali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5301,0,NULL,'pia','pima bajo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5302,0,NULL,'pib','yine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5303,0,NULL,'pic','pinji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5304,0,NULL,'pid','piaroa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5305,0,NULL,'pie','piro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5306,0,NULL,'pif','pingelapese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5307,0,NULL,'pig','pisabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5308,0,NULL,'pih','pitcairn-norfolk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5309,0,NULL,'pii','pini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5310,0,NULL,'pij','pijao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5311,0,NULL,'pil','yom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5312,0,NULL,'pim','powhatan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5313,0,NULL,'pin','piame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5314,0,NULL,'pio','piapoco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5315,0,NULL,'pip','pero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5316,0,NULL,'pir','piratapuyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5317,0,NULL,'pis','pijin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5318,0,NULL,'pit','pitta pitta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5319,0,NULL,'piu','pintupi-luritja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5320,0,NULL,'piv','pileni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5320,0,NULL,'piv','vaeakau-taumako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5321,0,NULL,'piw','pimbwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5322,0,NULL,'pix','piu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5323,0,NULL,'piy','piya-kwonci','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5324,0,NULL,'piz','pije','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5325,0,NULL,'pjt','pitjantjatjara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5326,0,NULL,'pka','ardhamāgadhī prākrit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5327,0,NULL,'pkb','kipfokomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5327,0,NULL,'pkb','pokomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5328,0,NULL,'pkc','paekche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5329,0,NULL,'pkg','pak-tong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5330,0,NULL,'pkh','pankhu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5331,0,NULL,'pkn','pakanha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5332,0,NULL,'pko','pökoot','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(5333,0,NULL,'pkp','pukapuka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5334,0,NULL,'pkr','attapady kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5335,0,NULL,'pks','pakistan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5336,0,NULL,'pkt','maleng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5337,0,NULL,'pku','paku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5338,0,NULL,'pla','miani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5339,0,NULL,'plb','polonombauk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5340,0,NULL,'plc','central palawano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5341,0,NULL,'pld','polari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5342,0,NULL,'ple','palu''e','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5343,0,NULL,'plf','central malayo-polynesian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5344,0,NULL,'plg','pilagá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5345,0,NULL,'plh','paulohi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5346,0,NULL,'plj','polci','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5347,0,NULL,'plk','kohistani shina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5348,0,NULL,'pll','shwe palaung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5349,0,NULL,'pln','palenquero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5350,0,NULL,'plo','oluta popoluca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5351,0,NULL,'plp','palpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5352,0,NULL,'plq','palaic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5353,0,NULL,'plr','palaka senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5354,0,NULL,'pls','san marcos tlalcoyalco popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5355,0,NULL,'plt','plateau malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(5356,0,NULL,'plu','palikúr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5357,0,NULL,'plv','southwest palawano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5358,0,NULL,'plw','brooke''s point palawano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5359,0,NULL,'ply','bolyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5360,0,NULL,'plz','paluan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5361,0,NULL,'pma','paama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5362,0,NULL,'pmb','pambia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5363,0,NULL,'pmc','palumata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5364,0,NULL,'pme','pwaamei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5365,0,NULL,'pmf','pamona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5366,0,NULL,'pmh','māhārāṣṭri prākrit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5367,0,NULL,'pmi','northern pumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5368,0,NULL,'pmj','southern pumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5369,0,NULL,'pmk','pamlico','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5370,0,NULL,'pml','lingua franca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5371,0,NULL,'pmm','pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5372,0,NULL,'pmn','pam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5373,0,NULL,'pmo','pom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5374,0,NULL,'pmq','northern pame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5375,0,NULL,'pmr','paynamar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5376,0,NULL,'pms','piemontese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5377,0,NULL,'pmt','tuamotuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5378,0,NULL,'pmu','mirpur panjabi','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(5379,0,NULL,'pmw','plains miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5380,0,NULL,'pmx','poumei naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5381,0,NULL,'pmy','papuan malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5382,0,NULL,'pmz','southern pame','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5383,0,NULL,'pna','punan bah-biau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5384,0,NULL,'pnb','western panjabi','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(5385,0,NULL,'pnc','pannei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5386,0,NULL,'pne','western penan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5387,0,NULL,'png','pongu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5388,0,NULL,'pnh','penrhyn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5389,0,NULL,'pni','aoheng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5390,0,NULL,'pnm','punan batu 1','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5391,0,NULL,'pnn','pinai-hagahai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5392,0,NULL,'pno','panobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5393,0,NULL,'pnp','pancana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5394,0,NULL,'pnq','pana (burkina faso)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5395,0,NULL,'pnr','panim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5396,0,NULL,'pns','ponosakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5397,0,NULL,'pnt','pontic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5398,0,NULL,'pnu','jiongnai bunu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5399,0,NULL,'pnv','pinigura','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5400,0,NULL,'pnw','panytyima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5401,0,NULL,'pnx','phong-kniang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5402,0,NULL,'pny','pinyin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,'a niger-congo language spoken in cameroon; not to be confused with the pinyin romanization systems used for chinese and tibetan'); +INSERT INTO "iana_records" VALUES(5403,0,NULL,'pnz','pana (central african republic)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5404,0,NULL,'poc','poqomam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5405,0,NULL,'pod','ponares','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5406,0,NULL,'poe','san juan atzingo popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5407,0,NULL,'pof','poke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5408,0,NULL,'pog','potiguára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5409,0,NULL,'poh','poqomchi''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5410,0,NULL,'poi','highland popoluca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5411,0,NULL,'pok','pokangá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5412,0,NULL,'pom','southeastern pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5413,0,NULL,'pon','pohnpeian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5414,0,NULL,'poo','central pomo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5415,0,NULL,'pop','pwapwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5416,0,NULL,'poq','texistepec popoluca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5417,0,NULL,'pos','sayula popoluca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5418,0,NULL,'pot','potawatomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5419,0,NULL,'pov','upper guinea crioulo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5420,0,NULL,'pow','san felipe otlaltepec popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5421,0,NULL,'pox','polabian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5422,0,NULL,'poy','pogolo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5423,0,NULL,'poz','malayo-polynesian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5424,0,NULL,'ppa','pao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5425,0,NULL,'ppe','papi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5426,0,NULL,'ppi','paipai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5427,0,NULL,'ppk','uma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5428,0,NULL,'ppl','nicarao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5428,0,NULL,'ppl','pipil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5429,0,NULL,'ppm','papuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5430,0,NULL,'ppn','papapana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5431,0,NULL,'ppo','folopa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5432,0,NULL,'ppp','pelende','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5433,0,NULL,'ppq','pei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5434,0,NULL,'ppr','piru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5435,0,NULL,'pps','san luís temalacayuca popoloca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5436,0,NULL,'ppt','pare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5437,0,NULL,'ppu','papora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5438,0,NULL,'pqa','pa''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5439,0,NULL,'pqe','eastern malayo-polynesian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5440,0,NULL,'pqm','malecite-passamaquoddy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5441,0,NULL,'pqw','western malayo-polynesian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5442,0,NULL,'pra','prakrit languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5443,0,NULL,'prb','lua''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5444,0,NULL,'prc','parachi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5445,0,NULL,'prd','parsi-dari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5446,0,NULL,'pre','principense','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5447,0,NULL,'prf','paranan','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5448,0,NULL,'prg','prussian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5449,0,NULL,'prh','porohanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5450,0,NULL,'pri','paicî','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5451,0,NULL,'prk','parauk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5452,0,NULL,'prl','peruvian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5453,0,NULL,'prm','kibiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5454,0,NULL,'prn','prasuni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5455,0,NULL,'pro','old occitan (to 1500)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5455,0,NULL,'pro','old provençal (to 1500)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5456,0,NULL,'prp','parsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5457,0,NULL,'prq','ashéninka perené','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5458,0,NULL,'prr','puri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5459,0,NULL,'prs','afghan persian','1248825600',NULL,NULL,NULL,NULL,'fa',NULL,NULL); +INSERT INTO "iana_records" VALUES(5459,0,NULL,'prs','dari','1248825600',NULL,NULL,NULL,NULL,'fa',NULL,NULL); +INSERT INTO "iana_records" VALUES(5460,0,NULL,'prt','phai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5461,0,NULL,'pru','puragi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5462,0,NULL,'prw','parawen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5463,0,NULL,'prx','purik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5464,0,NULL,'pry','pray 3','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5465,0,NULL,'prz','providencia sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5466,0,NULL,'psa','asue awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5467,0,NULL,'psc','persian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5468,0,NULL,'psd','plains indian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5469,0,NULL,'pse','central malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(5470,0,NULL,'psg','penang sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5471,0,NULL,'psh','southwest pashayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5472,0,NULL,'psi','southeast pashayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5473,0,NULL,'psl','puerto rican sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5474,0,NULL,'psm','pauserna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5475,0,NULL,'psn','panasuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5476,0,NULL,'pso','polish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5477,0,NULL,'psp','philippine sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5478,0,NULL,'psq','pasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5479,0,NULL,'psr','portuguese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5480,0,NULL,'pss','kaulong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5481,0,NULL,'pst','central pashto','1248825600',NULL,NULL,NULL,NULL,'ps',NULL,NULL); +INSERT INTO "iana_records" VALUES(5482,0,NULL,'psu','sauraseni prākrit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5483,0,NULL,'psw','port sandwich','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5484,0,NULL,'psy','piscataway','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5485,0,NULL,'pta','pai tavytera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5486,0,NULL,'pth','pataxó hã-ha-hãe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5487,0,NULL,'pti','pintiini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5488,0,NULL,'ptn','patani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5489,0,NULL,'pto','zo''é','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5490,0,NULL,'ptp','patep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5491,0,NULL,'ptr','piamatsina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5492,0,NULL,'ptt','enrekang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5493,0,NULL,'ptu','bambam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5494,0,NULL,'ptv','port vato','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5495,0,NULL,'ptw','pentlatch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5496,0,NULL,'pty','pathiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5497,0,NULL,'pua','western highland purepecha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5498,0,NULL,'pub','purum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5499,0,NULL,'puc','punan merap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5500,0,NULL,'pud','punan aput','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5501,0,NULL,'pue','puelche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5502,0,NULL,'puf','punan merah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5503,0,NULL,'pug','phuie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5504,0,NULL,'pui','puinave','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5505,0,NULL,'puj','punan tubu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5506,0,NULL,'puk','pu ko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5507,0,NULL,'pum','puma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5508,0,NULL,'puo','puoc','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5509,0,NULL,'pup','pulabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5510,0,NULL,'puq','puquina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5511,0,NULL,'pur','puruborá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5512,0,NULL,'put','putoh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5513,0,NULL,'puu','punu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5514,0,NULL,'puw','puluwatese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5515,0,NULL,'pux','puare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5516,0,NULL,'puy','purisimeño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5517,0,NULL,'puz','purum naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5518,0,NULL,'pwa','pawaia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5519,0,NULL,'pwb','panawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5520,0,NULL,'pwg','gapapaiwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5521,0,NULL,'pwm','molbog','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5522,0,NULL,'pwn','paiwan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5523,0,NULL,'pwo','pwo western karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5524,0,NULL,'pwr','powari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5525,0,NULL,'pww','pwo northern karen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5526,0,NULL,'pxm','quetzaltepec mixe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5527,0,NULL,'pye','pye krumen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5528,0,NULL,'pym','fyam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5529,0,NULL,'pyn','poyanáwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5530,0,NULL,'pys','lengua de señas del paraguay','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5530,0,NULL,'pys','paraguayan sign language','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5531,0,NULL,'pyu','puyuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5532,0,NULL,'pyx','pyu (myanmar)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5533,0,NULL,'pyy','pyen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5534,0,NULL,'pzn','para naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5535,0,NULL,'qaa..qtz','private use','1129420800',NULL,NULL,NULL,NULL,NULL,'private-use',NULL); +INSERT INTO "iana_records" VALUES(5536,0,NULL,'qua','quapaw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5537,0,NULL,'qub','huallaga huánuco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5538,0,NULL,'quc','k''iche''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5538,0,NULL,'quc','quiché','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5539,0,NULL,'qud','calderón highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5540,0,NULL,'quf','lambayeque quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5541,0,NULL,'qug','chimborazo highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5542,0,NULL,'quh','south bolivian quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5543,0,NULL,'qui','quileute','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5544,0,NULL,'quk','chachapoyas quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5545,0,NULL,'qul','north bolivian quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5546,0,NULL,'qum','sipacapense','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5547,0,NULL,'qun','quinault','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5548,0,NULL,'qup','southern pastaza quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5549,0,NULL,'quq','quinqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5550,0,NULL,'qur','yanahuanca pasco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5551,0,NULL,'qus','santiago del estero quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5552,0,NULL,'quv','sacapulteco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5553,0,NULL,'quw','tena lowland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5554,0,NULL,'qux','yauyos quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5555,0,NULL,'quy','ayacucho quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5556,0,NULL,'quz','cusco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5557,0,NULL,'qva','ambo-pasco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5558,0,NULL,'qvc','cajamarca quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5559,0,NULL,'qve','eastern apurímac quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5560,0,NULL,'qvh','huamalíes-dos de mayo huánuco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5561,0,NULL,'qvi','imbabura highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5562,0,NULL,'qvj','loja highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5563,0,NULL,'qvl','cajatambo north lima quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5564,0,NULL,'qvm','margos-yarowilca-lauricocha quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5565,0,NULL,'qvn','north junín quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5566,0,NULL,'qvo','napo lowland quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5567,0,NULL,'qvp','pacaraos quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5568,0,NULL,'qvs','san martín quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5569,0,NULL,'qvw','huaylla wanca quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5570,0,NULL,'qvy','queyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5571,0,NULL,'qvz','northern pastaza quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5572,0,NULL,'qwa','corongo ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5573,0,NULL,'qwc','classical quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5574,0,NULL,'qwe','quechuan (family)','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5575,0,NULL,'qwh','huaylas ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5576,0,NULL,'qwm','kuman (russia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5577,0,NULL,'qws','sihuas ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5578,0,NULL,'qwt','kwalhioqua-tlatskanai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5579,0,NULL,'qxa','chiquián ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5580,0,NULL,'qxc','chincha quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5581,0,NULL,'qxh','panao huánuco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5582,0,NULL,'qxl','salasaca highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5583,0,NULL,'qxn','northern conchucos ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5584,0,NULL,'qxo','southern conchucos ancash quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5585,0,NULL,'qxp','puno quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5586,0,NULL,'qxq','qashqa''i','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5587,0,NULL,'qxr','cañar highland quichua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5588,0,NULL,'qxs','southern qiang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5589,0,NULL,'qxt','santa ana de tusi pasco quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5590,0,NULL,'qxu','arequipa-la unión quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5591,0,NULL,'qxw','jauja wanca quechua','1248825600',NULL,NULL,NULL,NULL,'qu',NULL,NULL); +INSERT INTO "iana_records" VALUES(5592,0,NULL,'qya','quenya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5593,0,NULL,'qyp','quiripi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5594,0,NULL,'raa','dungmali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5595,0,NULL,'rab','camling','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5596,0,NULL,'rac','rasawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5597,0,NULL,'rad','rade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5598,0,NULL,'raf','western meohang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5599,0,NULL,'rag','logooli','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(5599,0,NULL,'rag','lulogooli','1248825600',NULL,NULL,NULL,NULL,'luy',NULL,NULL); +INSERT INTO "iana_records" VALUES(5600,0,NULL,'rah','rabha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5601,0,NULL,'rai','ramoaaina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5602,0,NULL,'raj','rajasthani','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(5603,0,NULL,'rak','tulu-bohuai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5604,0,NULL,'ral','ralte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5605,0,NULL,'ram','canela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5606,0,NULL,'ran','riantana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5607,0,NULL,'rao','rao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5608,0,NULL,'rap','rapanui','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5609,0,NULL,'raq','saam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5610,0,NULL,'rar','cook islands maori','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5610,0,NULL,'rar','rarotongan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5611,0,NULL,'ras','tegali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5612,0,NULL,'rat','razajerdi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5613,0,NULL,'rau','raute','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5614,0,NULL,'rav','sampang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5615,0,NULL,'raw','rawang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5616,0,NULL,'rax','rang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5617,0,NULL,'ray','rapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5618,0,NULL,'raz','rahambuu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5619,0,NULL,'rbb','rumai palaung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5620,0,NULL,'rbk','northern bontok','1268265600',NULL,NULL,NULL,NULL,'bnc',NULL,NULL); +INSERT INTO "iana_records" VALUES(5621,0,NULL,'rbl','miraya bikol','1268265600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(5622,0,NULL,'rcf','réunion creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5623,0,NULL,'rdb','rudbari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5624,0,NULL,'rea','rerau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5625,0,NULL,'reb','rembong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5626,0,NULL,'ree','rejang kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5627,0,NULL,'reg','kara (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5628,0,NULL,'rei','reli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5629,0,NULL,'rej','rejang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5630,0,NULL,'rel','rendille','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5631,0,NULL,'rem','remo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5632,0,NULL,'ren','rengao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5633,0,NULL,'rer','rer bare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5634,0,NULL,'res','reshe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5635,0,NULL,'ret','retta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5636,0,NULL,'rey','reyesano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5637,0,NULL,'rga','roria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5638,0,NULL,'rge','romano-greek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5639,0,NULL,'rgk','rangkas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5640,0,NULL,'rgn','romagnol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5641,0,NULL,'rgr','resígaro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5642,0,NULL,'rgs','southern roglai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5643,0,NULL,'rgu','ringgou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5644,0,NULL,'rhg','rohingya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5645,0,NULL,'rhp','yahang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5646,0,NULL,'ria','riang (india)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5647,0,NULL,'rie','rien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5648,0,NULL,'rif','tarifit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5649,0,NULL,'ril','riang (myanmar)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5650,0,NULL,'rim','nyaturu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5651,0,NULL,'rin','nungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5652,0,NULL,'rir','ribun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5653,0,NULL,'rit','ritarungo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5654,0,NULL,'riu','riung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5655,0,NULL,'rjg','rajong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5656,0,NULL,'rji','raji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5657,0,NULL,'rjs','rajbanshi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5658,0,NULL,'rka','kraol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5659,0,NULL,'rkb','rikbaktsa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5660,0,NULL,'rkh','rakahanga-manihiki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5661,0,NULL,'rki','rakhine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5662,0,NULL,'rkm','marka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5663,0,NULL,'rkt','kamta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5663,0,NULL,'rkt','rangpuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5664,0,NULL,'rma','rama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5665,0,NULL,'rmb','rembarunga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5666,0,NULL,'rmc','carpathian romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5667,0,NULL,'rmd','traveller danish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5668,0,NULL,'rme','angloromani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5669,0,NULL,'rmf','kalo finnish romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5670,0,NULL,'rmg','traveller norwegian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5671,0,NULL,'rmh','murkim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5672,0,NULL,'rmi','lomavren','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5673,0,NULL,'rmk','romkun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5674,0,NULL,'rml','baltic romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5675,0,NULL,'rmm','roma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5676,0,NULL,'rmn','balkan romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5677,0,NULL,'rmo','sinte romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5678,0,NULL,'rmp','rempi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5679,0,NULL,'rmq','caló','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5680,0,NULL,'rmr','caló','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see emx, rmq'); +INSERT INTO "iana_records" VALUES(5681,0,NULL,'rms','romanian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5682,0,NULL,'rmt','domari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5683,0,NULL,'rmu','tavringer romani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5684,0,NULL,'rmv','romanova','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5685,0,NULL,'rmw','welsh romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5686,0,NULL,'rmx','romam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5687,0,NULL,'rmy','vlax romani','1248825600',NULL,NULL,NULL,NULL,'rom',NULL,NULL); +INSERT INTO "iana_records" VALUES(5688,0,NULL,'rmz','marma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5689,0,NULL,'rna','runa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5690,0,NULL,'rnd','ruund','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5691,0,NULL,'rng','ronga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5692,0,NULL,'rnl','ranglong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5693,0,NULL,'rnn','roon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5694,0,NULL,'rnp','rongpo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5695,0,NULL,'rnw','rungwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5696,0,NULL,'roa','romance languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5697,0,NULL,'rob','tae''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5698,0,NULL,'roc','cacgia roglai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5699,0,NULL,'rod','rogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5700,0,NULL,'roe','ronji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5701,0,NULL,'rof','rombo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5702,0,NULL,'rog','northern roglai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5703,0,NULL,'rol','romblomanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5704,0,NULL,'rom','romany','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(5705,0,NULL,'roo','rotokas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5706,0,NULL,'rop','kriol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5707,0,NULL,'ror','rongga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5708,0,NULL,'rou','runga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5709,0,NULL,'row','dela-oenale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5710,0,NULL,'rpn','repanbitip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5711,0,NULL,'rpt','rapting','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5712,0,NULL,'rri','ririo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5713,0,NULL,'rro','waima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5714,0,NULL,'rsb','romano-serbian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5715,0,NULL,'rsi','rennellese sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5716,0,NULL,'rsl','russian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5717,0,NULL,'rth','ratahan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5718,0,NULL,'rtm','rotuman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5719,0,NULL,'rtw','rathawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5720,0,NULL,'rub','gungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5721,0,NULL,'ruc','ruuli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5722,0,NULL,'rue','rusyn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5723,0,NULL,'ruf','luguru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5724,0,NULL,'rug','roviana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5725,0,NULL,'ruh','ruga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5726,0,NULL,'rui','rufiji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5727,0,NULL,'ruk','che','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5728,0,NULL,'ruo','istro romanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5729,0,NULL,'rup','aromanian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5729,0,NULL,'rup','arumanian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5729,0,NULL,'rup','macedo-romanian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5730,0,NULL,'ruq','megleno romanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5731,0,NULL,'rut','rutul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5732,0,NULL,'ruu','lanas lobu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5733,0,NULL,'ruy','mala (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5734,0,NULL,'ruz','ruma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5735,0,NULL,'rwa','rawo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5736,0,NULL,'rwk','rwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5737,0,NULL,'rwm','amba (uganda)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5738,0,NULL,'rwo','rawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5739,0,NULL,'rwr','marwari (india)','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(5740,0,NULL,'ryn','northern amami-oshima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5741,0,NULL,'rys','yaeyama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5742,0,NULL,'ryu','central okinawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5743,0,NULL,'saa','saba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5744,0,NULL,'sab','buglere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5745,0,NULL,'sac','meskwaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5746,0,NULL,'sad','sandawe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5747,0,NULL,'sae','sabanê','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5748,0,NULL,'saf','safaliba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5749,0,NULL,'sah','yakut','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5750,0,NULL,'sai','south american indian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5751,0,NULL,'saj','sahu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5752,0,NULL,'sak','sake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5753,0,NULL,'sal','salishan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5754,0,NULL,'sam','samaritan aramaic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5755,0,NULL,'sao','sause','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5756,0,NULL,'sap','sanapaná','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5757,0,NULL,'saq','samburu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5758,0,NULL,'sar','saraveca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5759,0,NULL,'sas','sasak','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5760,0,NULL,'sat','santali','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5761,0,NULL,'sau','saleman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5762,0,NULL,'sav','saafi-saafi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5763,0,NULL,'saw','sawi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5764,0,NULL,'sax','sa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5765,0,NULL,'say','saya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5766,0,NULL,'saz','saurashtra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5767,0,NULL,'sba','ngambay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5768,0,NULL,'sbb','simbo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5769,0,NULL,'sbc','kele (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5770,0,NULL,'sbd','southern samo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5771,0,NULL,'sbe','saliba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5772,0,NULL,'sbf','shabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5773,0,NULL,'sbg','seget','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5774,0,NULL,'sbh','sori-harengan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5775,0,NULL,'sbi','seti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5776,0,NULL,'sbj','surbakhal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5777,0,NULL,'sbk','safwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5778,0,NULL,'sbl','botolan sambal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5779,0,NULL,'sbm','sagala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5780,0,NULL,'sbn','sindhi bhil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5781,0,NULL,'sbo','sabüm','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5782,0,NULL,'sbp','sangu (tanzania)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5783,0,NULL,'sbq','sileibi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5784,0,NULL,'sbr','sembakung murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5785,0,NULL,'sbs','subiya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5786,0,NULL,'sbt','kimki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5787,0,NULL,'sbu','stod bhoti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5788,0,NULL,'sbv','sabine','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5789,0,NULL,'sbw','simba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5790,0,NULL,'sbx','seberuang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5791,0,NULL,'sby','soli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5792,0,NULL,'sbz','sara kaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5793,0,NULL,'sca','sansu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5794,0,NULL,'scb','chut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5795,0,NULL,'sce','dongxiang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5796,0,NULL,'scf','san miguel creole french','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5797,0,NULL,'scg','sanggau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5798,0,NULL,'sch','sakachep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5799,0,NULL,'sci','sri lankan creole malay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5800,0,NULL,'sck','sadri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5801,0,NULL,'scl','shina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5802,0,NULL,'scn','sicilian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5803,0,NULL,'sco','scots','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5804,0,NULL,'scp','helambu sherpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5805,0,NULL,'scq','sa''och','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5806,0,NULL,'scs','north slavey','1248825600',NULL,NULL,NULL,NULL,'den',NULL,NULL); +INSERT INTO "iana_records" VALUES(5807,0,NULL,'scu','shumcho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5808,0,NULL,'scv','sheni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5809,0,NULL,'scw','sha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5810,0,NULL,'scx','sicel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5811,0,NULL,'sda','toraja-sa''dan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5812,0,NULL,'sdb','shabak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5813,0,NULL,'sdc','sassarese sardinian','1248825600',NULL,NULL,NULL,NULL,'sc',NULL,NULL); +INSERT INTO "iana_records" VALUES(5814,0,NULL,'sde','surubu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5815,0,NULL,'sdf','sarli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5816,0,NULL,'sdg','savi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5817,0,NULL,'sdh','southern kurdish','1248825600',NULL,NULL,NULL,NULL,'ku',NULL,NULL); +INSERT INTO "iana_records" VALUES(5818,0,NULL,'sdj','suundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5819,0,NULL,'sdk','sos kundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5820,0,NULL,'sdl','saudi arabian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5821,0,NULL,'sdm','semandang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5822,0,NULL,'sdn','gallurese sardinian','1248825600',NULL,NULL,NULL,NULL,'sc',NULL,NULL); +INSERT INTO "iana_records" VALUES(5823,0,NULL,'sdo','bukar-sadung bidayuh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5824,0,NULL,'sdp','sherdukpen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5825,0,NULL,'sdr','oraon sadri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5826,0,NULL,'sds','sened','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5827,0,NULL,'sdt','shuadit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5828,0,NULL,'sdu','sarudu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5829,0,NULL,'sdv','eastern sudanic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5830,0,NULL,'sdx','sibu melanau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5831,0,NULL,'sdz','sallands','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5832,0,NULL,'sea','semai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5833,0,NULL,'seb','shempire senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5834,0,NULL,'sec','sechelt','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5835,0,NULL,'sed','sedang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5836,0,NULL,'see','seneca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5837,0,NULL,'sef','cebaara senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5838,0,NULL,'seg','segeju','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5839,0,NULL,'seh','sena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5840,0,NULL,'sei','seri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5841,0,NULL,'sej','sene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5842,0,NULL,'sek','sekani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5843,0,NULL,'sel','selkup','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5844,0,NULL,'sem','semitic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5845,0,NULL,'sen','nanerigé sénoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5846,0,NULL,'seo','suarmin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5847,0,NULL,'sep','sìcìté sénoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5848,0,NULL,'seq','senara sénoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5849,0,NULL,'ser','serrano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5850,0,NULL,'ses','koyraboro senni songhai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5851,0,NULL,'set','sentani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5852,0,NULL,'seu','serui-laut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5853,0,NULL,'sev','nyarafolo senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5854,0,NULL,'sew','sewa bay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5855,0,NULL,'sey','secoya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5856,0,NULL,'sez','senthang chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5857,0,NULL,'sfb','french belgian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5857,0,NULL,'sfb','langue des signes de belgique francophone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5858,0,NULL,'sfm','small flowery miao','1248825600',NULL,NULL,NULL,NULL,'hmn',NULL,NULL); +INSERT INTO "iana_records" VALUES(5859,0,NULL,'sfs','south african sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5860,0,NULL,'sfw','sehwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5861,0,NULL,'sga','old irish (to 900)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5862,0,NULL,'sgb','mag-antsi ayta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5863,0,NULL,'sgc','kipsigis','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(5864,0,NULL,'sgd','surigaonon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5865,0,NULL,'sge','segai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5866,0,NULL,'sgg','swiss-german sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5867,0,NULL,'sgh','shughni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5868,0,NULL,'sgi','suga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5869,0,NULL,'sgk','sangkong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5870,0,NULL,'sgl','sanglechi-ishkashimi','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see isk, sgy'); +INSERT INTO "iana_records" VALUES(5871,0,NULL,'sgm','singa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5872,0,NULL,'sgn','sign languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5873,0,NULL,'sgo','songa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5874,0,NULL,'sgp','singpho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5875,0,NULL,'sgr','sangisari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5876,0,NULL,'sgt','brokpake','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5877,0,NULL,'sgu','salas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5878,0,NULL,'sgw','sebat bet gurage','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5879,0,NULL,'sgx','sierra leone sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5880,0,NULL,'sgy','sanglechi','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5881,0,NULL,'sgz','sursurunga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5882,0,NULL,'sha','shall-zwall','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5883,0,NULL,'shb','ninam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5884,0,NULL,'shc','sonde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5885,0,NULL,'shd','kundal shahi','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5886,0,NULL,'she','sheko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5887,0,NULL,'shg','shua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5888,0,NULL,'shh','shoshoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5889,0,NULL,'shi','tachelhit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5890,0,NULL,'shj','shatt','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5891,0,NULL,'shk','shilluk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5892,0,NULL,'shl','shendu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5893,0,NULL,'shm','shahrudi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5894,0,NULL,'shn','shan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5895,0,NULL,'sho','shanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5896,0,NULL,'shp','shipibo-conibo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5897,0,NULL,'shq','sala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5898,0,NULL,'shr','shi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5899,0,NULL,'shs','shuswap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5900,0,NULL,'sht','shasta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5901,0,NULL,'shu','chadian arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(5902,0,NULL,'shv','shehri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5903,0,NULL,'shw','shwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5904,0,NULL,'shx','she','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5905,0,NULL,'shy','tachawit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5906,0,NULL,'shz','syenara senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5907,0,NULL,'sia','akkala sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5908,0,NULL,'sib','sebop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5909,0,NULL,'sid','sidamo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5910,0,NULL,'sie','simaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5911,0,NULL,'sif','siamou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5912,0,NULL,'sig','paasaal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5913,0,NULL,'sih','zire','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5914,0,NULL,'sii','shom peng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5915,0,NULL,'sij','numbami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5916,0,NULL,'sik','sikiana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5917,0,NULL,'sil','tumulung sisaala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5918,0,NULL,'sim','mende (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5919,0,NULL,'sio','siouan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5920,0,NULL,'sip','sikkimese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5921,0,NULL,'siq','sonia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5922,0,NULL,'sir','siri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5923,0,NULL,'sis','siuslaw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5924,0,NULL,'sit','sino-tibetan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5925,0,NULL,'siu','sinagen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5926,0,NULL,'siv','sumariup','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5927,0,NULL,'siw','siwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5928,0,NULL,'six','sumau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5929,0,NULL,'siy','sivandi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5930,0,NULL,'siz','siwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5931,0,NULL,'sja','epena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5932,0,NULL,'sjb','sajau basap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5933,0,NULL,'sjd','kildin sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5934,0,NULL,'sje','pite sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5935,0,NULL,'sjg','assangori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5936,0,NULL,'sjk','kemi sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5937,0,NULL,'sjl','miji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5937,0,NULL,'sjl','sajalong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5938,0,NULL,'sjm','mapun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5939,0,NULL,'sjn','sindarin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5940,0,NULL,'sjo','xibe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5941,0,NULL,'sjp','surjapuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5942,0,NULL,'sjr','siar-lak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5943,0,NULL,'sjs','senhaja de srair','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5944,0,NULL,'sjt','ter sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5945,0,NULL,'sju','ume sami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5946,0,NULL,'sjw','shawnee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5947,0,NULL,'ska','skagit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5948,0,NULL,'skb','saek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5949,0,NULL,'skc','sauk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5950,0,NULL,'skd','southern sierra miwok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5951,0,NULL,'ske','seke (vanuatu)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5952,0,NULL,'skf','sakirabiá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5953,0,NULL,'skg','sakalava malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(5954,0,NULL,'skh','sikule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5955,0,NULL,'ski','sika','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5956,0,NULL,'skj','seke (nepal)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5957,0,NULL,'skk','sok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5958,0,NULL,'skm','sakam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5959,0,NULL,'skn','kolibugan subanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5960,0,NULL,'sko','seko tengah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5961,0,NULL,'skp','sekapan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5962,0,NULL,'skq','sininkere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5963,0,NULL,'skr','seraiki','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(5964,0,NULL,'sks','maia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5965,0,NULL,'skt','sakata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5966,0,NULL,'sku','sakao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5967,0,NULL,'skv','skou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5968,0,NULL,'skw','skepi creole dutch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5969,0,NULL,'skx','seko padang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5970,0,NULL,'sky','sikaiana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5971,0,NULL,'skz','sekar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5972,0,NULL,'sla','slavic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(5973,0,NULL,'slc','sáliba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5974,0,NULL,'sld','sissala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5975,0,NULL,'sle','sholaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5976,0,NULL,'slf','swiss-italian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5977,0,NULL,'slg','selungai murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5978,0,NULL,'slh','southern puget sound salish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5979,0,NULL,'sli','lower silesian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5980,0,NULL,'slj','salumá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5981,0,NULL,'sll','salt-yui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5982,0,NULL,'slm','pangutaran sama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5983,0,NULL,'sln','salinan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5984,0,NULL,'slp','lamaholot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5985,0,NULL,'slq','salchuq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5986,0,NULL,'slr','salar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5987,0,NULL,'sls','singapore sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5988,0,NULL,'slt','sila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5989,0,NULL,'slu','selaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5990,0,NULL,'slw','sialum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5991,0,NULL,'slx','salampasu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5992,0,NULL,'sly','selayar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5993,0,NULL,'slz','ma''ya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5994,0,NULL,'sma','southern sami','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5995,0,NULL,'smb','simbari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5996,0,NULL,'smc','som','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5997,0,NULL,'smd','sama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5998,0,NULL,'smf','auwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(5999,0,NULL,'smg','simbali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6000,0,NULL,'smh','samei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6001,0,NULL,'smi','sami languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6002,0,NULL,'smj','lule sami','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6003,0,NULL,'smk','bolinao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6004,0,NULL,'sml','central sama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6005,0,NULL,'smm','musasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6006,0,NULL,'smn','inari sami','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6007,0,NULL,'smp','samaritan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6008,0,NULL,'smq','samo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6009,0,NULL,'smr','simeulue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6010,0,NULL,'sms','skolt sami','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6011,0,NULL,'smt','simte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6012,0,NULL,'smu','somray','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6013,0,NULL,'smv','samvedi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6014,0,NULL,'smw','sumbawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6015,0,NULL,'smx','samba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6016,0,NULL,'smy','semnani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6017,0,NULL,'smz','simeku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6018,0,NULL,'snb','sebuyau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6019,0,NULL,'snc','sinaugoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6020,0,NULL,'sne','bau bidayuh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6021,0,NULL,'snf','noon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6022,0,NULL,'sng','sanga (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6023,0,NULL,'snh','shinabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6024,0,NULL,'sni','sensi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6025,0,NULL,'snj','riverain sango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6026,0,NULL,'snk','soninke','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6027,0,NULL,'snl','sangil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6028,0,NULL,'snm','southern ma''di','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6029,0,NULL,'snn','siona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6030,0,NULL,'sno','snohomish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6031,0,NULL,'snp','siane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6032,0,NULL,'snq','sangu (gabon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6033,0,NULL,'snr','sihan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6034,0,NULL,'sns','nahavaq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6034,0,NULL,'sns','south west bay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6035,0,NULL,'snu','senggi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6035,0,NULL,'snu','viid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6036,0,NULL,'snv','sa''ban','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6037,0,NULL,'snw','selee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6038,0,NULL,'snx','sam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6039,0,NULL,'sny','saniyo-hiyewe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6040,0,NULL,'snz','sinsauru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6041,0,NULL,'soa','thai song','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6042,0,NULL,'sob','sobei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6043,0,NULL,'soc','so (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6044,0,NULL,'sod','songoora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6045,0,NULL,'soe','songomeno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6046,0,NULL,'sog','sogdian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6047,0,NULL,'soh','aka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6048,0,NULL,'soi','sonha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6049,0,NULL,'soj','soi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6050,0,NULL,'sok','sokoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6051,0,NULL,'sol','solos','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6052,0,NULL,'son','songhai languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6053,0,NULL,'soo','songo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6054,0,NULL,'sop','songe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6055,0,NULL,'soq','kanasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6056,0,NULL,'sor','somrai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6057,0,NULL,'sos','seeku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6058,0,NULL,'sou','southern thai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6059,0,NULL,'sov','sonsorol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6060,0,NULL,'sow','sowanda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6061,0,NULL,'sox','so (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6062,0,NULL,'soy','miyobe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6063,0,NULL,'soz','temi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6064,0,NULL,'spb','sepa (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6065,0,NULL,'spc','sapé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6066,0,NULL,'spd','saep','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6067,0,NULL,'spe','sepa (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6068,0,NULL,'spg','sian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6069,0,NULL,'spi','saponi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6070,0,NULL,'spk','sengo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6071,0,NULL,'spl','selepet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6072,0,NULL,'spm','sepen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6073,0,NULL,'spo','spokane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6074,0,NULL,'spp','supyire senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6075,0,NULL,'spq','loreto-ucayali spanish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6076,0,NULL,'spr','saparua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6077,0,NULL,'sps','saposa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6078,0,NULL,'spt','spiti bhoti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6079,0,NULL,'spu','sapuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6080,0,NULL,'spx','south picene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6081,0,NULL,'spy','sabaot','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(6082,0,NULL,'sqa','shama-sambuga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6083,0,NULL,'sqh','shau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6084,0,NULL,'sqj','albanian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6085,0,NULL,'sqm','suma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6086,0,NULL,'sqn','susquehannock','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6087,0,NULL,'sqo','sorkhei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6088,0,NULL,'sqq','sou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6089,0,NULL,'sqr','siculo arabic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6090,0,NULL,'sqs','sri lankan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6091,0,NULL,'sqt','soqotri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6092,0,NULL,'squ','squamish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6093,0,NULL,'sra','saruga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6094,0,NULL,'srb','sora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6095,0,NULL,'src','logudorese sardinian','1248825600',NULL,NULL,NULL,NULL,'sc',NULL,NULL); +INSERT INTO "iana_records" VALUES(6096,0,NULL,'sre','sara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6097,0,NULL,'srf','nafi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6098,0,NULL,'srg','sulod','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6099,0,NULL,'srh','sarikoli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6100,0,NULL,'sri','siriano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6101,0,NULL,'srk','serudung murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6102,0,NULL,'srl','isirawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6103,0,NULL,'srm','saramaccan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6104,0,NULL,'srn','sranan tongo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6105,0,NULL,'sro','campidanese sardinian','1248825600',NULL,NULL,NULL,NULL,'sc',NULL,NULL); +INSERT INTO "iana_records" VALUES(6106,0,NULL,'srq','sirionó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6107,0,NULL,'srr','serer','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6108,0,NULL,'srs','sarsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6109,0,NULL,'srt','sauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6110,0,NULL,'sru','suruí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6111,0,NULL,'srv','southern sorsoganon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6112,0,NULL,'srw','serua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6113,0,NULL,'srx','sirmauri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6114,0,NULL,'sry','sera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6115,0,NULL,'srz','shahmirzadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6116,0,NULL,'ssa','nilo-saharan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6117,0,NULL,'ssb','southern sama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6118,0,NULL,'ssc','suba-simbiti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6119,0,NULL,'ssd','siroi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6120,0,NULL,'sse','balangingi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6120,0,NULL,'sse','bangingih sama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6121,0,NULL,'ssf','thao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6122,0,NULL,'ssg','seimat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6123,0,NULL,'ssh','shihhi arabic','1248825600',NULL,NULL,NULL,NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(6124,0,NULL,'ssi','sansi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6125,0,NULL,'ssj','sausi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6126,0,NULL,'ssk','sunam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6127,0,NULL,'ssl','western sisaala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6128,0,NULL,'ssm','semnam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6129,0,NULL,'ssn','waata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6130,0,NULL,'sso','sissano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6131,0,NULL,'ssp','spanish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6132,0,NULL,'ssq','so''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6133,0,NULL,'ssr','swiss-french sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6134,0,NULL,'sss','sô','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6135,0,NULL,'sst','sinasina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6136,0,NULL,'ssu','susuami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6137,0,NULL,'ssv','shark bay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6138,0,NULL,'ssx','samberigi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6139,0,NULL,'ssy','saho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6140,0,NULL,'ssz','sengseng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6141,0,NULL,'sta','settla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6142,0,NULL,'stb','northern subanen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6143,0,NULL,'std','sentinel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6144,0,NULL,'ste','liana-seti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6145,0,NULL,'stf','seta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6146,0,NULL,'stg','trieng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6147,0,NULL,'sth','shelta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6148,0,NULL,'sti','bulo stieng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6149,0,NULL,'stj','matya samo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6150,0,NULL,'stk','arammba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6151,0,NULL,'stl','stellingwerfs','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6152,0,NULL,'stm','setaman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6153,0,NULL,'stn','owa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6154,0,NULL,'sto','stoney','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6155,0,NULL,'stp','southeastern tepehuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6156,0,NULL,'stq','saterfriesisch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6157,0,NULL,'str','straits salish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6158,0,NULL,'sts','shumashti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6159,0,NULL,'stt','budeh stieng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6160,0,NULL,'stu','samtao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6161,0,NULL,'stv','silt''e','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6162,0,NULL,'stw','satawalese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6163,0,NULL,'sua','sulka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6164,0,NULL,'sub','suku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6165,0,NULL,'suc','western subanon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6166,0,NULL,'sue','suena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6167,0,NULL,'sug','suganga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6168,0,NULL,'sui','suki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6169,0,NULL,'suj','shubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6170,0,NULL,'suk','sukuma','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6171,0,NULL,'sul','surigaonon','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see sgd, tgn'); +INSERT INTO "iana_records" VALUES(6172,0,NULL,'sum','sumo-mayangna','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see ulw, yan'); +INSERT INTO "iana_records" VALUES(6173,0,NULL,'suq','suri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6174,0,NULL,'sur','mwaghavul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6175,0,NULL,'sus','susu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6176,0,NULL,'sut','subtiaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6177,0,NULL,'suv','sulung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6178,0,NULL,'suw','sumbwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6179,0,NULL,'sux','sumerian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6180,0,NULL,'suy','suyá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6181,0,NULL,'suz','sunwar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6182,0,NULL,'sva','svan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6183,0,NULL,'svb','ulau-suain','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6184,0,NULL,'svc','vincentian creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6185,0,NULL,'sve','serili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6186,0,NULL,'svk','slovakian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6187,0,NULL,'svr','savara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6188,0,NULL,'svs','savosavo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6189,0,NULL,'svx','skalvian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6190,0,NULL,'swb','maore comorian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6191,0,NULL,'swc','congo swahili','1248825600',NULL,NULL,NULL,NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(6192,0,NULL,'swf','sere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6193,0,NULL,'swg','swabian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6194,0,NULL,'swh','kiswahili','1248825600',NULL,NULL,NULL,NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(6194,0,NULL,'swh','swahili (individual language)','1248825600',NULL,NULL,NULL,NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(6195,0,NULL,'swi','sui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6196,0,NULL,'swj','sira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6197,0,NULL,'swk','malawi sena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6198,0,NULL,'swl','swedish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6199,0,NULL,'swm','samosa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6200,0,NULL,'swn','sawknah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6201,0,NULL,'swo','shanenawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6202,0,NULL,'swp','suau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6203,0,NULL,'swq','sharwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6204,0,NULL,'swr','saweru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6205,0,NULL,'sws','seluwasan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6206,0,NULL,'swt','sawila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6207,0,NULL,'swu','suwawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6208,0,NULL,'swv','shekhawati','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(6209,0,NULL,'sww','sowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6210,0,NULL,'swx','suruahá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6211,0,NULL,'swy','sarua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6212,0,NULL,'sxb','suba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6213,0,NULL,'sxc','sicanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6214,0,NULL,'sxe','sighu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6215,0,NULL,'sxg','shixing','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6216,0,NULL,'sxk','southern kalapuya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6217,0,NULL,'sxl','selian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6218,0,NULL,'sxm','samre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6219,0,NULL,'sxn','sangir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6220,0,NULL,'sxo','sorothaptic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6221,0,NULL,'sxr','saaroa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6222,0,NULL,'sxs','sasaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6223,0,NULL,'sxu','upper saxon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6224,0,NULL,'sxw','saxwe gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6225,0,NULL,'sya','siang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6226,0,NULL,'syb','central subanen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6227,0,NULL,'syc','classical syriac','1175558400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6228,0,NULL,'syd','samoyedic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6229,0,NULL,'syi','seki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6230,0,NULL,'syk','sukur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6231,0,NULL,'syl','sylheti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6232,0,NULL,'sym','maya samo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6233,0,NULL,'syn','senaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6234,0,NULL,'syo','suoy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6235,0,NULL,'syr','syriac','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(6236,0,NULL,'sys','sinyar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6237,0,NULL,'syw','kagate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6238,0,NULL,'syy','al-sayyid bedouin sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6239,0,NULL,'sza','semelai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6240,0,NULL,'szb','ngalum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6241,0,NULL,'szc','semaq beri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6242,0,NULL,'szd','seru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6243,0,NULL,'sze','seze','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6244,0,NULL,'szg','sengele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6245,0,NULL,'szl','silesian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6246,0,NULL,'szn','sula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6247,0,NULL,'szp','suabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6248,0,NULL,'szv','isu (fako division)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6249,0,NULL,'szw','sawai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6250,0,NULL,'taa','lower tanana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6251,0,NULL,'tab','tabassaran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6252,0,NULL,'tac','lowland tarahumara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6253,0,NULL,'tad','tause','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6254,0,NULL,'tae','tariana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6255,0,NULL,'taf','tapirapé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6256,0,NULL,'tag','tagoi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6257,0,NULL,'tai','tai languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6258,0,NULL,'taj','eastern tamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6259,0,NULL,'tak','tala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6260,0,NULL,'tal','tal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6261,0,NULL,'tan','tangale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6262,0,NULL,'tao','yami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6263,0,NULL,'tap','taabwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6264,0,NULL,'taq','tamasheq','1248825600',NULL,NULL,NULL,NULL,'tmh',NULL,NULL); +INSERT INTO "iana_records" VALUES(6265,0,NULL,'tar','central tarahumara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6266,0,NULL,'tas','tay boi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6267,0,NULL,'tau','upper tanana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6268,0,NULL,'tav','tatuyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6269,0,NULL,'taw','tai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6270,0,NULL,'tax','tamki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6271,0,NULL,'tay','atayal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6272,0,NULL,'taz','tocho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6273,0,NULL,'tba','aikanã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6274,0,NULL,'tbb','tapeba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6275,0,NULL,'tbc','takia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6276,0,NULL,'tbd','kaki ae','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6277,0,NULL,'tbe','tanimbili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6278,0,NULL,'tbf','mandara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6279,0,NULL,'tbg','north tairora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6280,0,NULL,'tbh','thurawal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6281,0,NULL,'tbi','gaam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6282,0,NULL,'tbj','tiang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6283,0,NULL,'tbk','calamian tagbanwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6284,0,NULL,'tbl','tboli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6285,0,NULL,'tbm','tagbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6286,0,NULL,'tbn','barro negro tunebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6287,0,NULL,'tbo','tawala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6288,0,NULL,'tbp','diebroud','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6288,0,NULL,'tbp','taworta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6289,0,NULL,'tbq','tibeto-burman languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6290,0,NULL,'tbr','tumtum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6291,0,NULL,'tbs','tanguat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6292,0,NULL,'tbt','tembo (kitembo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6293,0,NULL,'tbu','tubar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6294,0,NULL,'tbv','tobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6295,0,NULL,'tbw','tagbanwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6296,0,NULL,'tbx','kapin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6297,0,NULL,'tby','tabaru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6298,0,NULL,'tbz','ditammari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6299,0,NULL,'tca','ticuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6300,0,NULL,'tcb','tanacross','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6301,0,NULL,'tcc','datooga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6302,0,NULL,'tcd','tafi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6303,0,NULL,'tce','southern tutchone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6304,0,NULL,'tcf','malinaltepec me''phaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6304,0,NULL,'tcf','malinaltepec tlapanec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6305,0,NULL,'tcg','tamagario','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6306,0,NULL,'tch','turks and caicos creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6307,0,NULL,'tci','wára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6308,0,NULL,'tck','tchitchege','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6309,0,NULL,'tcl','taman (myanmar)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6310,0,NULL,'tcm','tanahmerah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6311,0,NULL,'tcn','tichurong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6312,0,NULL,'tco','taungyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6313,0,NULL,'tcp','tawr chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6314,0,NULL,'tcq','kaiy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6315,0,NULL,'tcs','torres strait creole','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6316,0,NULL,'tct','t''en','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6317,0,NULL,'tcu','southeastern tarahumara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6318,0,NULL,'tcw','tecpatlán totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6319,0,NULL,'tcx','toda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6320,0,NULL,'tcy','tulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6321,0,NULL,'tcz','thado chin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6322,0,NULL,'tda','tagdal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6323,0,NULL,'tdb','panchpargania','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6324,0,NULL,'tdc','emberá-tadó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6325,0,NULL,'tdd','tai nüa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6326,0,NULL,'tde','tiranige diga dogon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6327,0,NULL,'tdf','talieng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6328,0,NULL,'tdg','western tamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6329,0,NULL,'tdh','thulung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6330,0,NULL,'tdi','tomadino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6331,0,NULL,'tdj','tajio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6332,0,NULL,'tdk','tambas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6333,0,NULL,'tdl','sur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6334,0,NULL,'tdn','tondano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6335,0,NULL,'tdo','teme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6336,0,NULL,'tdq','tita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6337,0,NULL,'tdr','todrah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6338,0,NULL,'tds','doutai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6339,0,NULL,'tdt','tetun dili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6340,0,NULL,'tdu','tempasuk dusun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6341,0,NULL,'tdv','toro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6342,0,NULL,'tdx','tandroy-mahafaly malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(6343,0,NULL,'tdy','tadyawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6344,0,NULL,'tea','temiar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6345,0,NULL,'teb','tetete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6346,0,NULL,'tec','terik','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(6347,0,NULL,'ted','tepo krumen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6348,0,NULL,'tee','huehuetla tepehua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6349,0,NULL,'tef','teressa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6350,0,NULL,'teg','teke-tege','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6351,0,NULL,'teh','tehuelche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6352,0,NULL,'tei','torricelli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6353,0,NULL,'tek','ibali teke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6354,0,NULL,'tem','timne','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6355,0,NULL,'ten','tama (colombia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6356,0,NULL,'teo','teso','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6357,0,NULL,'tep','tepecano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6358,0,NULL,'teq','temein','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6359,0,NULL,'ter','tereno','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6360,0,NULL,'tes','tengger','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6361,0,NULL,'tet','tetum','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6362,0,NULL,'teu','soo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6363,0,NULL,'tev','teor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6364,0,NULL,'tew','tewa (usa)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6365,0,NULL,'tex','tennet','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6366,0,NULL,'tey','tulishi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6367,0,NULL,'tfi','tofin gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6368,0,NULL,'tfn','tanaina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6369,0,NULL,'tfo','tefaro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6370,0,NULL,'tfr','teribe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6371,0,NULL,'tft','ternate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6372,0,NULL,'tga','sagalla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6373,0,NULL,'tgb','tobilung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6374,0,NULL,'tgc','tigak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6375,0,NULL,'tgd','ciwogai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6376,0,NULL,'tge','eastern gorkha tamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6377,0,NULL,'tgf','chalikha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6378,0,NULL,'tgg','tangga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6379,0,NULL,'tgh','tobagonian creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6380,0,NULL,'tgi','lawunuia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6381,0,NULL,'tgn','tandaganon','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6382,0,NULL,'tgo','sudest','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6383,0,NULL,'tgp','tangoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6384,0,NULL,'tgq','tring','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6385,0,NULL,'tgr','tareng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6386,0,NULL,'tgs','nume','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6387,0,NULL,'tgt','central tagbanwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6388,0,NULL,'tgu','tanggu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6389,0,NULL,'tgv','tingui-boto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6390,0,NULL,'tgw','tagwana senoufo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6391,0,NULL,'tgx','tagish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6392,0,NULL,'tgy','togoyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6393,0,NULL,'thc','tai hang tong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6394,0,NULL,'thd','thayore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6395,0,NULL,'the','chitwania tharu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6396,0,NULL,'thf','thangmi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6397,0,NULL,'thh','northern tarahumara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6398,0,NULL,'thi','tai long','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6399,0,NULL,'thk','kitharaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6399,0,NULL,'thk','tharaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6400,0,NULL,'thl','dangaura tharu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6401,0,NULL,'thm','aheu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6402,0,NULL,'thn','thachanadan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6403,0,NULL,'thp','thompson','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6404,0,NULL,'thq','kochila tharu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6405,0,NULL,'thr','rana tharu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6406,0,NULL,'ths','thakali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6407,0,NULL,'tht','tahltan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6408,0,NULL,'thu','thuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6409,0,NULL,'thv','tahaggart tamahaq','1248825600',NULL,NULL,NULL,NULL,'tmh',NULL,NULL); +INSERT INTO "iana_records" VALUES(6410,0,NULL,'thw','thudam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6411,0,NULL,'thx','the','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6412,0,NULL,'thy','tha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6413,0,NULL,'thz','tayart tamajeq','1248825600',NULL,NULL,NULL,NULL,'tmh',NULL,NULL); +INSERT INTO "iana_records" VALUES(6414,0,NULL,'tia','tidikelt tamazight','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6415,0,NULL,'tic','tira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6416,0,NULL,'tid','tidong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6417,0,NULL,'tie','tingal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6418,0,NULL,'tif','tifal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6419,0,NULL,'tig','tigre','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6420,0,NULL,'tih','timugon murut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6421,0,NULL,'tii','tiene','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6422,0,NULL,'tij','tilung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6423,0,NULL,'tik','tikar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6424,0,NULL,'til','tillamook','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6425,0,NULL,'tim','timbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6426,0,NULL,'tin','tindi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6427,0,NULL,'tio','teop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6428,0,NULL,'tip','trimuris','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6429,0,NULL,'tiq','tiéfo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6430,0,NULL,'tis','masadiit itneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6431,0,NULL,'tit','tinigua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6432,0,NULL,'tiu','adasen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6433,0,NULL,'tiv','tiv','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6434,0,NULL,'tiw','tiwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6435,0,NULL,'tix','southern tiwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6436,0,NULL,'tiy','tiruray','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6437,0,NULL,'tiz','tai hongjin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6438,0,NULL,'tja','tajuasohn','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6439,0,NULL,'tjg','tunjung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6440,0,NULL,'tji','northern tujia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6441,0,NULL,'tjm','timucua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6442,0,NULL,'tjn','tonjon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6443,0,NULL,'tjo','temacine tamazight','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6444,0,NULL,'tjs','southern tujia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6445,0,NULL,'tju','tjurruru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6446,0,NULL,'tka','truká','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6447,0,NULL,'tkb','buksa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6448,0,NULL,'tkd','tukudede','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6449,0,NULL,'tke','takwane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6450,0,NULL,'tkf','tukumanféd','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6451,0,NULL,'tkk','takpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6452,0,NULL,'tkl','tokelau','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6453,0,NULL,'tkm','takelma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6454,0,NULL,'tkn','toku-no-shima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6455,0,NULL,'tkp','tikopia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6456,0,NULL,'tkq','tee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6457,0,NULL,'tkr','tsakhur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6458,0,NULL,'tks','takestani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6459,0,NULL,'tkt','kathoriya tharu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6460,0,NULL,'tku','upper necaxa totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6461,0,NULL,'tkw','teanu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6462,0,NULL,'tkx','tangko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6463,0,NULL,'tkz','takua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6464,0,NULL,'tla','southwestern tepehuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6465,0,NULL,'tlb','tobelo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6466,0,NULL,'tlc','yecuatla totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6467,0,NULL,'tld','talaud','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6468,0,NULL,'tlf','telefol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6469,0,NULL,'tlg','tofanma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6470,0,NULL,'tlh','klingon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6470,0,NULL,'tlh','tlhingan-hol','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6471,0,NULL,'tli','tlingit','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6472,0,NULL,'tlj','talinga-bwisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6473,0,NULL,'tlk','taloki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6474,0,NULL,'tll','tetela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6475,0,NULL,'tlm','tolomako','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6476,0,NULL,'tln','talondo''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6477,0,NULL,'tlo','talodi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6478,0,NULL,'tlp','filomena mata-coahuitlán totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6479,0,NULL,'tlq','tai loi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6480,0,NULL,'tlr','talise','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6481,0,NULL,'tls','tambotalo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6482,0,NULL,'tlt','teluti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6483,0,NULL,'tlu','tulehu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6484,0,NULL,'tlv','taliabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6485,0,NULL,'tlw','south wemale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6486,0,NULL,'tlx','khehek','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6487,0,NULL,'tly','talysh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6488,0,NULL,'tma','tama (chad)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6489,0,NULL,'tmb','avava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6489,0,NULL,'tmb','katbol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6490,0,NULL,'tmc','tumak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6491,0,NULL,'tmd','haruai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6492,0,NULL,'tme','tremembé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6493,0,NULL,'tmf','toba-maskoy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6494,0,NULL,'tmg','ternateño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6495,0,NULL,'tmh','tamashek','1129420800',NULL,NULL,NULL,'latn',NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(6496,0,NULL,'tmi','tutuba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6497,0,NULL,'tmj','samarokena','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6498,0,NULL,'tmk','northwestern tamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6499,0,NULL,'tml','tamnim citak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6500,0,NULL,'tmm','tai thanh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6501,0,NULL,'tmn','taman (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6502,0,NULL,'tmo','temoq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6503,0,NULL,'tmp','tai mène','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6504,0,NULL,'tmq','tumleo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6505,0,NULL,'tmr','jewish babylonian aramaic (ca. 200-1200 ce)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6506,0,NULL,'tms','tima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6507,0,NULL,'tmt','tasmate','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6508,0,NULL,'tmu','iau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6509,0,NULL,'tmv','tembo (motembo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6510,0,NULL,'tmw','temuan','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(6511,0,NULL,'tmy','tami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6512,0,NULL,'tmz','tamanaku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6513,0,NULL,'tna','tacana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6514,0,NULL,'tnb','western tunebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6515,0,NULL,'tnc','tanimuca-retuarã','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6516,0,NULL,'tnd','angosturas tunebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6517,0,NULL,'tne','tinoc kallahan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6518,0,NULL,'tnf','tangshewi','1248825600',1268265600,'prs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6519,0,NULL,'tng','tobanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6520,0,NULL,'tnh','maiani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6521,0,NULL,'tni','tandia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6522,0,NULL,'tnk','kwamera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6523,0,NULL,'tnl','lenakel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6524,0,NULL,'tnm','tabla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6525,0,NULL,'tnn','north tanna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6526,0,NULL,'tno','toromono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6527,0,NULL,'tnp','whitesands','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6528,0,NULL,'tnq','taino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6529,0,NULL,'tnr','bedik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6530,0,NULL,'tns','tenis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6531,0,NULL,'tnt','tontemboan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6532,0,NULL,'tnu','tay khang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6533,0,NULL,'tnv','tangchangya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6534,0,NULL,'tnw','tonsawang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6535,0,NULL,'tnx','tanema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6536,0,NULL,'tny','tongwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6537,0,NULL,'tnz','tonga (thailand)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6538,0,NULL,'tob','toba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6539,0,NULL,'toc','coyutla totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6540,0,NULL,'tod','toma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6541,0,NULL,'toe','tomedes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6542,0,NULL,'tof','gizrra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6543,0,NULL,'tog','tonga (nyasa)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6544,0,NULL,'toh','gitonga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6545,0,NULL,'toi','tonga (zambia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6546,0,NULL,'toj','tojolabal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6547,0,NULL,'tol','tolowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6548,0,NULL,'tom','tombulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6549,0,NULL,'too','xicotepec de juárez totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6550,0,NULL,'top','papantla totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6551,0,NULL,'toq','toposa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6552,0,NULL,'tor','togbo-vara banda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6553,0,NULL,'tos','highland totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6554,0,NULL,'tou','tho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6555,0,NULL,'tov','upper taromi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6556,0,NULL,'tow','jemez','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6557,0,NULL,'tox','tobian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6558,0,NULL,'toy','topoiyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6559,0,NULL,'toz','to','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6560,0,NULL,'tpa','taupota','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6561,0,NULL,'tpc','azoyú me''phaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6561,0,NULL,'tpc','azoyú tlapanec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6562,0,NULL,'tpe','tippera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6563,0,NULL,'tpf','tarpia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6564,0,NULL,'tpg','kula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6565,0,NULL,'tpi','tok pisin','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6566,0,NULL,'tpj','tapieté','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6567,0,NULL,'tpk','tupinikin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6568,0,NULL,'tpl','tlacoapa me''phaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6568,0,NULL,'tpl','tlacoapa tlapanec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6569,0,NULL,'tpm','tampulma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6570,0,NULL,'tpn','tupinambá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6571,0,NULL,'tpo','tai pao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6572,0,NULL,'tpp','pisaflores tepehua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6573,0,NULL,'tpq','tukpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6574,0,NULL,'tpr','tuparí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6575,0,NULL,'tpt','tlachichilco tepehua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6576,0,NULL,'tpu','tampuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6577,0,NULL,'tpv','tanapag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6578,0,NULL,'tpw','tupí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6579,0,NULL,'tpx','acatepec me''phaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6579,0,NULL,'tpx','acatepec tlapanec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6580,0,NULL,'tpy','trumai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6581,0,NULL,'tpz','tinputz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6582,0,NULL,'tqb','tembé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6583,0,NULL,'tql','lehali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6584,0,NULL,'tqm','turumsa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6585,0,NULL,'tqn','tenino','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6586,0,NULL,'tqo','toaripi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6587,0,NULL,'tqp','tomoip','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6588,0,NULL,'tqq','tunni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6589,0,NULL,'tqr','torona','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6590,0,NULL,'tqt','western totonac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6591,0,NULL,'tqu','touo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6592,0,NULL,'tqw','tonkawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6593,0,NULL,'tra','tirahi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6594,0,NULL,'trb','terebu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6595,0,NULL,'trc','copala triqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6596,0,NULL,'trd','turi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6597,0,NULL,'tre','east tarangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6598,0,NULL,'trf','trinidadian creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6599,0,NULL,'trg','lishán didán','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6600,0,NULL,'trh','turaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6601,0,NULL,'tri','trió','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6602,0,NULL,'trj','toram','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6603,0,NULL,'trk','turkic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6604,0,NULL,'trl','traveller scottish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6605,0,NULL,'trm','tregami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6606,0,NULL,'trn','trinitario','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6607,0,NULL,'tro','tarao naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6608,0,NULL,'trp','kok borok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6609,0,NULL,'trq','san martín itunyoso triqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6610,0,NULL,'trr','taushiro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6611,0,NULL,'trs','chicahuaxtla triqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6612,0,NULL,'trt','tunggare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6613,0,NULL,'tru','turoyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6614,0,NULL,'trv','taroko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6615,0,NULL,'trw','torwali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6616,0,NULL,'trx','tringgus-sembaan bidayuh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6617,0,NULL,'try','turung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6618,0,NULL,'trz','torá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6619,0,NULL,'tsa','tsaangi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6620,0,NULL,'tsb','tsamai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6621,0,NULL,'tsc','tswa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6622,0,NULL,'tsd','tsakonian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6623,0,NULL,'tse','tunisian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6624,0,NULL,'tsf','southwestern tamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6625,0,NULL,'tsg','tausug','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6626,0,NULL,'tsh','tsuvan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6627,0,NULL,'tsi','tsimshian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6628,0,NULL,'tsj','tshangla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6629,0,NULL,'tsk','tseku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6630,0,NULL,'tsl','ts''ün-lao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6631,0,NULL,'tsm','turkish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6631,0,NULL,'tsm','türk İşaret dili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6632,0,NULL,'tsp','northern toussian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6633,0,NULL,'tsq','thai sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6634,0,NULL,'tsr','akei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6635,0,NULL,'tss','taiwan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6636,0,NULL,'tsu','tsou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6637,0,NULL,'tsv','tsogo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6638,0,NULL,'tsw','tsishingini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6639,0,NULL,'tsx','mubami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6640,0,NULL,'tsy','tebul sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6641,0,NULL,'tsz','purepecha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6642,0,NULL,'tta','tutelo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6643,0,NULL,'ttb','gaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6644,0,NULL,'ttc','tektiteko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6645,0,NULL,'ttd','tauade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6646,0,NULL,'tte','bwanabwana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6647,0,NULL,'ttf','tuotomb','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6648,0,NULL,'ttg','tutong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6649,0,NULL,'tth','upper ta''oih','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6650,0,NULL,'tti','tobati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6651,0,NULL,'ttj','tooro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6652,0,NULL,'ttk','totoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6653,0,NULL,'ttl','totela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6654,0,NULL,'ttm','northern tutchone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6655,0,NULL,'ttn','towei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6656,0,NULL,'tto','lower ta''oih','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6657,0,NULL,'ttp','tombelala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6658,0,NULL,'ttq','tawallammat tamajaq','1248825600',NULL,NULL,NULL,NULL,'tmh',NULL,NULL); +INSERT INTO "iana_records" VALUES(6659,0,NULL,'ttr','tera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6660,0,NULL,'tts','northeastern thai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6661,0,NULL,'ttt','muslim tat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6662,0,NULL,'ttu','torau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6663,0,NULL,'ttv','titan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6664,0,NULL,'ttw','long wat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6665,0,NULL,'tty','sikaritai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6666,0,NULL,'ttz','tsum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6667,0,NULL,'tua','wiarumus','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6668,0,NULL,'tub','tübatulabal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6669,0,NULL,'tuc','mutu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6670,0,NULL,'tud','tuxá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6671,0,NULL,'tue','tuyuca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6672,0,NULL,'tuf','central tunebo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6673,0,NULL,'tug','tunia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6674,0,NULL,'tuh','taulil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6675,0,NULL,'tui','tupuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6676,0,NULL,'tuj','tugutil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6677,0,NULL,'tul','tula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6678,0,NULL,'tum','tumbuka','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6679,0,NULL,'tun','tunica','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6680,0,NULL,'tuo','tucano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6681,0,NULL,'tup','tupi languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6682,0,NULL,'tuq','tedaga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6683,0,NULL,'tus','tuscarora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6684,0,NULL,'tut','altaic languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6685,0,NULL,'tuu','tututni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6686,0,NULL,'tuv','turkana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6687,0,NULL,'tuw','tungus languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6688,0,NULL,'tux','tuxináwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6689,0,NULL,'tuy','tugen','1248825600',NULL,NULL,NULL,NULL,'kln',NULL,NULL); +INSERT INTO "iana_records" VALUES(6690,0,NULL,'tuz','turka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6691,0,NULL,'tva','vaghua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6692,0,NULL,'tvd','tsuvadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6693,0,NULL,'tve','te''un','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6694,0,NULL,'tvk','southeast ambrym','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6695,0,NULL,'tvl','tuvalu','1129420800',NULL,NULL,NULL,'latn',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6696,0,NULL,'tvm','tela-masbuar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6697,0,NULL,'tvn','tavoyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6698,0,NULL,'tvo','tidore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6699,0,NULL,'tvs','taveta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6700,0,NULL,'tvt','tutsa naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6701,0,NULL,'tvw','sedoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6702,0,NULL,'tvy','timor pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6703,0,NULL,'twa','twana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6704,0,NULL,'twb','western tawbuid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6705,0,NULL,'twc','teshenawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6706,0,NULL,'twd','twents','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6707,0,NULL,'twe','tewa (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6708,0,NULL,'twf','northern tiwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6709,0,NULL,'twg','tereweng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6710,0,NULL,'twh','tai dón','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6711,0,NULL,'twl','tawara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6712,0,NULL,'twm','tawang monpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6713,0,NULL,'twn','twendi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6714,0,NULL,'two','tswapong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6715,0,NULL,'twp','ere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6716,0,NULL,'twq','tasawaq','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6717,0,NULL,'twr','southwestern tarahumara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6718,0,NULL,'twt','turiwára','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6719,0,NULL,'twu','termanu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6720,0,NULL,'tww','tuwari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6721,0,NULL,'twx','tewe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6722,0,NULL,'twy','tawoyan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6723,0,NULL,'txa','tombonuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6724,0,NULL,'txb','tokharian b','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6725,0,NULL,'txc','tsetsaut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6726,0,NULL,'txe','totoli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6727,0,NULL,'txg','tangut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6728,0,NULL,'txh','thracian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6729,0,NULL,'txi','ikpeng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6730,0,NULL,'txm','tomini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6731,0,NULL,'txn','west tarangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6732,0,NULL,'txo','toto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6733,0,NULL,'txq','tii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6734,0,NULL,'txr','tartessian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6735,0,NULL,'txs','tonsea','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6736,0,NULL,'txt','citak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6737,0,NULL,'txu','kayapó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6738,0,NULL,'txx','tatana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6739,0,NULL,'txy','tanosy malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(6740,0,NULL,'tya','tauya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6741,0,NULL,'tye','kyenga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6742,0,NULL,'tyh','o''du','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6743,0,NULL,'tyi','teke-tsaayi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6744,0,NULL,'tyj','tai do','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6745,0,NULL,'tyl','thu lao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6746,0,NULL,'tyn','kombai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6747,0,NULL,'typ','thaypan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6748,0,NULL,'tyr','tai daeng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6749,0,NULL,'tys','tày sa pa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6750,0,NULL,'tyt','tày tac','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6751,0,NULL,'tyu','kua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6752,0,NULL,'tyv','tuvinian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6753,0,NULL,'tyx','teke-tyee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6754,0,NULL,'tyz','tày','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6755,0,NULL,'tza','tanzanian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6756,0,NULL,'tzh','tzeltal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6757,0,NULL,'tzj','tz''utujil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6758,0,NULL,'tzm','central atlas tamazight','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6759,0,NULL,'tzn','tugun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6760,0,NULL,'tzo','tzotzil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6761,0,NULL,'tzx','tabriak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6762,0,NULL,'uam','uamué','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6763,0,NULL,'uan','kuan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6764,0,NULL,'uar','tairuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6765,0,NULL,'uba','ubang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6766,0,NULL,'ubi','ubi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6767,0,NULL,'ubl','buhi''non bikol','1268265600',NULL,NULL,NULL,NULL,'bik',NULL,NULL); +INSERT INTO "iana_records" VALUES(6768,0,NULL,'ubr','ubir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6769,0,NULL,'ubu','umbu-ungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6770,0,NULL,'uby','ubykh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6771,0,NULL,'uda','uda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6772,0,NULL,'ude','udihe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6773,0,NULL,'udg','muduga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6774,0,NULL,'udi','udi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6775,0,NULL,'udj','ujir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6776,0,NULL,'udl','wuzlam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6777,0,NULL,'udm','udmurt','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6778,0,NULL,'udu','uduk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6779,0,NULL,'ues','kioko','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6780,0,NULL,'ufi','ufim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6781,0,NULL,'uga','ugaritic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6782,0,NULL,'ugb','kuku-ugbanh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6783,0,NULL,'uge','ughele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6784,0,NULL,'ugn','ugandan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6785,0,NULL,'ugo','ugong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6786,0,NULL,'ugy','uruguayan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6787,0,NULL,'uha','uhami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6788,0,NULL,'uhn','damal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6789,0,NULL,'uis','uisai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6790,0,NULL,'uiv','iyive','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6791,0,NULL,'uji','tanjijili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6792,0,NULL,'uka','kaburi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6793,0,NULL,'ukg','ukuriguma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6794,0,NULL,'ukh','ukhwejo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6795,0,NULL,'ukl','ukrainian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6796,0,NULL,'ukp','ukpe-bayobiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6797,0,NULL,'ukq','ukwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6798,0,NULL,'uks','kaapor sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6798,0,NULL,'uks','urubú-kaapor sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6799,0,NULL,'uku','ukue','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6800,0,NULL,'ukw','ukwuani-aboh-ndoni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6801,0,NULL,'ula','fungwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6802,0,NULL,'ulb','ulukwumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6803,0,NULL,'ulc','ulch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6804,0,NULL,'ulf','afra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6804,0,NULL,'ulf','usku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6805,0,NULL,'uli','ulithian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6806,0,NULL,'ulk','meriam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6807,0,NULL,'ull','ullatan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6808,0,NULL,'ulm','ulumanda''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6809,0,NULL,'uln','unserdeutsch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6810,0,NULL,'ulu','uma'' lung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6811,0,NULL,'ulw','ulwa','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6812,0,NULL,'uma','umatilla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6813,0,NULL,'umb','umbundu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6814,0,NULL,'umc','marrucinian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6815,0,NULL,'umd','umbindhamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6816,0,NULL,'umg','umbuygamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6817,0,NULL,'umi','ukit','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6818,0,NULL,'umm','umon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6819,0,NULL,'umn','makyan naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6820,0,NULL,'umo','umotína','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6821,0,NULL,'ump','umpila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6822,0,NULL,'umr','umbugarla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6823,0,NULL,'ums','pendau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6824,0,NULL,'umu','munsee','1248825600',NULL,NULL,NULL,NULL,'del',NULL,NULL); +INSERT INTO "iana_records" VALUES(6825,0,NULL,'una','north watut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6826,0,NULL,'und','undetermined','1129420800',NULL,NULL,NULL,NULL,NULL,'special',NULL); +INSERT INTO "iana_records" VALUES(6827,0,NULL,'une','uneme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6828,0,NULL,'ung','ngarinyin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6829,0,NULL,'unk','enawené-nawé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6830,0,NULL,'unm','unami','1248825600',NULL,NULL,NULL,NULL,'del',NULL,NULL); +INSERT INTO "iana_records" VALUES(6831,0,NULL,'unp','worora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6832,0,NULL,'unr','mundari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6833,0,NULL,'unx','munda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6834,0,NULL,'unz','unde kaili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6835,0,NULL,'uok','uokha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6836,0,NULL,'upi','umeda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6837,0,NULL,'upv','uripiv-wala-rano-atchin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6838,0,NULL,'ura','urarina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6839,0,NULL,'urb','kaapor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6839,0,NULL,'urb','urubú-kaapor','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6840,0,NULL,'urc','urningangg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6841,0,NULL,'ure','uru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6842,0,NULL,'urf','uradhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6843,0,NULL,'urg','urigina','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6844,0,NULL,'urh','urhobo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6845,0,NULL,'uri','urim','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6846,0,NULL,'urj','uralic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6847,0,NULL,'urk','urak lawoi''','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(6848,0,NULL,'url','urali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6849,0,NULL,'urm','urapmin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6850,0,NULL,'urn','uruangnirin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6851,0,NULL,'uro','ura (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6852,0,NULL,'urp','uru-pa-in','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6853,0,NULL,'urr','lehalurup','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6853,0,NULL,'urr','löyöp','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6854,0,NULL,'urt','urat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6855,0,NULL,'uru','urumi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6856,0,NULL,'urv','uruava','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6857,0,NULL,'urw','sop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6858,0,NULL,'urx','urimo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6859,0,NULL,'ury','orya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6860,0,NULL,'urz','uru-eu-wau-wau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6861,0,NULL,'usa','usarufa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6862,0,NULL,'ush','ushojo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6863,0,NULL,'usi','usui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6864,0,NULL,'usk','usaghade','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6865,0,NULL,'usp','uspanteco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6866,0,NULL,'usu','uya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6867,0,NULL,'uta','otank','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6868,0,NULL,'ute','ute-southern paiute','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6869,0,NULL,'utp','amba (solomon islands)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6870,0,NULL,'utr','etulo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6871,0,NULL,'utu','utu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6872,0,NULL,'uum','urum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6873,0,NULL,'uun','kulon-pazeh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6874,0,NULL,'uur','ura (vanuatu)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6875,0,NULL,'uuu','u','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6876,0,NULL,'uve','west uvean','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6877,0,NULL,'uvh','uri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6878,0,NULL,'uvl','lote','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6879,0,NULL,'uwa','kuku-uwanh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6880,0,NULL,'uya','doko-uyanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6881,0,NULL,'uzn','northern uzbek','1248825600',NULL,NULL,NULL,NULL,'uz',NULL,NULL); +INSERT INTO "iana_records" VALUES(6882,0,NULL,'uzs','southern uzbek','1248825600',NULL,NULL,NULL,NULL,'uz',NULL,NULL); +INSERT INTO "iana_records" VALUES(6883,0,NULL,'vaa','vaagri booli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6884,0,NULL,'vae','vale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6885,0,NULL,'vaf','vafsi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6886,0,NULL,'vag','vagla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6887,0,NULL,'vah','varhadi-nagpuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6888,0,NULL,'vai','vai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6889,0,NULL,'vaj','vasekela bushman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6890,0,NULL,'val','vehes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6891,0,NULL,'vam','vanimo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6892,0,NULL,'van','valman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6893,0,NULL,'vao','vao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6894,0,NULL,'vap','vaiphei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6895,0,NULL,'var','huarijio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6896,0,NULL,'vas','vasavi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6897,0,NULL,'vau','vanuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6898,0,NULL,'vav','varli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6899,0,NULL,'vay','wayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6900,0,NULL,'vbb','southeast babar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6901,0,NULL,'vbk','southwestern bontok','1268265600',NULL,NULL,NULL,NULL,'bnc',NULL,NULL); +INSERT INTO "iana_records" VALUES(6902,0,NULL,'vec','venetian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6903,0,NULL,'ved','veddah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6904,0,NULL,'vel','veluws','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6905,0,NULL,'vem','vemgo-mabas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6906,0,NULL,'veo','ventureño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6907,0,NULL,'vep','veps','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6908,0,NULL,'ver','mom jango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6909,0,NULL,'vgr','vaghri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6910,0,NULL,'vgt','flemish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6910,0,NULL,'vgt','vlaamse gebarentaal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6911,0,NULL,'vic','virgin islands creole english','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6912,0,NULL,'vid','vidunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6913,0,NULL,'vif','vili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6914,0,NULL,'vig','viemo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6915,0,NULL,'vil','vilela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6916,0,NULL,'vin','vinza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6917,0,NULL,'vis','vishavan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6918,0,NULL,'vit','viti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6919,0,NULL,'viv','iduna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6920,0,NULL,'vka','kariyarra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6921,0,NULL,'vki','ija-zuba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6922,0,NULL,'vkj','kujarge','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6923,0,NULL,'vkk','kaur','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(6924,0,NULL,'vkl','kulisusu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6925,0,NULL,'vkm','kamakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6926,0,NULL,'vko','kodeoha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6927,0,NULL,'vkp','korlai creole portuguese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6928,0,NULL,'vkt','tenggarong kutai malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(6929,0,NULL,'vku','kurrama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6930,0,NULL,'vlp','valpei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6931,0,NULL,'vls','vlaams','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6932,0,NULL,'vma','martuyhunira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6933,0,NULL,'vmb','mbabaram','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6934,0,NULL,'vmc','juxtlahuaca mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6935,0,NULL,'vmd','mudu koraga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6936,0,NULL,'vme','east masela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6937,0,NULL,'vmf','mainfränkisch','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6938,0,NULL,'vmg','minigir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6939,0,NULL,'vmh','maraghei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6940,0,NULL,'vmi','miwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6941,0,NULL,'vmj','ixtayutla mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6942,0,NULL,'vmk','makhuwa-shirima','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6943,0,NULL,'vml','malgana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6944,0,NULL,'vmm','mitlatongo mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6945,0,NULL,'vmp','soyaltepec mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6946,0,NULL,'vmq','soyaltepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6947,0,NULL,'vmr','marenje','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6948,0,NULL,'vms','moksela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6949,0,NULL,'vmu','muluridyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6950,0,NULL,'vmv','valley maidu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6951,0,NULL,'vmw','makhuwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6952,0,NULL,'vmx','tamazola mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6953,0,NULL,'vmy','ayautla mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6954,0,NULL,'vmz','mazatlán mazatec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6955,0,NULL,'vnk','lovono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6955,0,NULL,'vnk','vano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6956,0,NULL,'vnm','neve''ei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6956,0,NULL,'vnm','vinmavis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6957,0,NULL,'vnp','vunapu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6958,0,NULL,'vor','voro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6959,0,NULL,'vot','votic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6960,0,NULL,'vra','vera''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6961,0,NULL,'vro','võro','1248825600',NULL,NULL,NULL,NULL,'et',NULL,NULL); +INSERT INTO "iana_records" VALUES(6962,0,NULL,'vrs','varisi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6963,0,NULL,'vrt','banam bay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6963,0,NULL,'vrt','burmbar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6964,0,NULL,'vsi','moldova sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6965,0,NULL,'vsl','venezuelan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6966,0,NULL,'vsv','llengua de signes valenciana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6966,0,NULL,'vsv','valencian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6967,0,NULL,'vto','vitou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6968,0,NULL,'vum','vumbu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6969,0,NULL,'vun','vunjo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6970,0,NULL,'vut','vute','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6971,0,NULL,'vwa','awa (china)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6972,0,NULL,'waa','walla walla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6973,0,NULL,'wab','wab','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6974,0,NULL,'wac','wasco-wishram','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6975,0,NULL,'wad','wandamen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6976,0,NULL,'wae','walser','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6977,0,NULL,'waf','wakoná','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6978,0,NULL,'wag','wa''ema','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6979,0,NULL,'wah','watubela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6980,0,NULL,'wai','wares','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6981,0,NULL,'waj','waffa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6982,0,NULL,'wak','wakashan languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(6983,0,NULL,'wal','wolaitta','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6983,0,NULL,'wal','wolaytta','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6984,0,NULL,'wam','wampanoag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6985,0,NULL,'wan','wan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6986,0,NULL,'wao','wappo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6987,0,NULL,'wap','wapishana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6988,0,NULL,'waq','wageman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6989,0,NULL,'war','waray (philippines)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6990,0,NULL,'was','washo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6991,0,NULL,'wat','kaninuwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6992,0,NULL,'wau','waurá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6993,0,NULL,'wav','waka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6994,0,NULL,'waw','waiwai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6995,0,NULL,'wax','watam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6996,0,NULL,'way','wayana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6997,0,NULL,'waz','wampur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6998,0,NULL,'wba','warao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(6999,0,NULL,'wbb','wabo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7000,0,NULL,'wbe','waritai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7001,0,NULL,'wbf','wara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7002,0,NULL,'wbh','wanda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7003,0,NULL,'wbi','vwanji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7004,0,NULL,'wbj','alagwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7005,0,NULL,'wbk','waigali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7006,0,NULL,'wbl','wakhi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7007,0,NULL,'wbm','wa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7008,0,NULL,'wbp','warlpiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7009,0,NULL,'wbq','waddar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7010,0,NULL,'wbr','wagdi','1248825600',NULL,NULL,NULL,NULL,'raj',NULL,NULL); +INSERT INTO "iana_records" VALUES(7011,0,NULL,'wbt','wanman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7012,0,NULL,'wbv','wajarri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7013,0,NULL,'wbw','woi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7014,0,NULL,'wca','yanomámi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7015,0,NULL,'wci','waci gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7016,0,NULL,'wdd','wandji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7017,0,NULL,'wdg','wadaginam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7018,0,NULL,'wdj','wadjiginy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7019,0,NULL,'wdu','wadjigu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7020,0,NULL,'wea','wewaw','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7021,0,NULL,'wec','wè western','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7022,0,NULL,'wed','wedau','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7023,0,NULL,'weh','weh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7024,0,NULL,'wei','were','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7025,0,NULL,'wem','weme gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7026,0,NULL,'wen','sorbian languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7027,0,NULL,'weo','north wemale','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7028,0,NULL,'wep','westphalien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7029,0,NULL,'wer','weri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7030,0,NULL,'wes','cameroon pidgin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7031,0,NULL,'wet','perai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7032,0,NULL,'weu','welaung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7033,0,NULL,'wew','wejewa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7034,0,NULL,'wfg','yafi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7034,0,NULL,'wfg','zorop','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7035,0,NULL,'wga','wagaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7036,0,NULL,'wgb','wagawaga','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7037,0,NULL,'wgg','wangganguru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7038,0,NULL,'wgi','wahgi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7039,0,NULL,'wgo','waigeo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7040,0,NULL,'wgw','wagawaga','1248825600',1268265600,NULL,NULL,NULL,NULL,NULL,'see wgb, ylb'); +INSERT INTO "iana_records" VALUES(7041,0,NULL,'wgy','warrgamay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7042,0,NULL,'wha','manusela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7043,0,NULL,'whg','north wahgi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7044,0,NULL,'whk','wahau kenyah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7045,0,NULL,'whu','wahau kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7046,0,NULL,'wib','southern toussian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7047,0,NULL,'wic','wichita','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7048,0,NULL,'wie','wik-epa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7049,0,NULL,'wif','wik-keyangan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7050,0,NULL,'wig','wik-ngathana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7051,0,NULL,'wih','wik-me''anha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7052,0,NULL,'wii','minidien','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7053,0,NULL,'wij','wik-iiyanh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7054,0,NULL,'wik','wikalkan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7055,0,NULL,'wil','wilawila','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7056,0,NULL,'wim','wik-mungkan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7057,0,NULL,'win','ho-chunk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7058,0,NULL,'wir','wiraféd','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7059,0,NULL,'wit','wintu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7060,0,NULL,'wiu','wiru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7061,0,NULL,'wiv','muduapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7062,0,NULL,'wiw','wirangu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7063,0,NULL,'wiy','wiyot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7064,0,NULL,'wja','waja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7065,0,NULL,'wji','warji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7066,0,NULL,'wka','kw''adza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7067,0,NULL,'wkb','kumbaran','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7068,0,NULL,'wkd','mo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7068,0,NULL,'wkd','wakde','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7069,0,NULL,'wkl','kalanadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7070,0,NULL,'wku','kunduvadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7071,0,NULL,'wkw','wakawaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7072,0,NULL,'wla','walio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7073,0,NULL,'wlc','mwali comorian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7074,0,NULL,'wle','wolane','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7075,0,NULL,'wlg','kunbarlang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7076,0,NULL,'wli','waioli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7077,0,NULL,'wlk','wailaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7078,0,NULL,'wll','wali (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7079,0,NULL,'wlm','middle welsh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7080,0,NULL,'wlo','wolio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7081,0,NULL,'wlr','wailapa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7082,0,NULL,'wls','wallisian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7083,0,NULL,'wlu','wuliwuli','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7084,0,NULL,'wlv','wichí lhamtés vejoz','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7085,0,NULL,'wlw','walak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7086,0,NULL,'wlx','wali (ghana)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7087,0,NULL,'wly','waling','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7088,0,NULL,'wma','mawa (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7089,0,NULL,'wmb','wambaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7090,0,NULL,'wmc','wamas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7091,0,NULL,'wmd','mamaindé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7092,0,NULL,'wme','wambule','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7093,0,NULL,'wmh','waima''a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7094,0,NULL,'wmi','wamin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7095,0,NULL,'wmm','maiwa (indonesia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7096,0,NULL,'wmn','waamwang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7097,0,NULL,'wmo','wom (papua new guinea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7098,0,NULL,'wms','wambon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7099,0,NULL,'wmt','walmajarri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7100,0,NULL,'wmw','mwani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7101,0,NULL,'wmx','womo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7102,0,NULL,'wnb','wanambre','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7103,0,NULL,'wnc','wantoat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7104,0,NULL,'wnd','wandarang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7105,0,NULL,'wne','waneci','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7106,0,NULL,'wng','wanggom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7107,0,NULL,'wni','ndzwani comorian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7108,0,NULL,'wnk','wanukaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7109,0,NULL,'wnm','wanggamala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7110,0,NULL,'wno','wano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7111,0,NULL,'wnp','wanap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7112,0,NULL,'wnu','usan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7113,0,NULL,'woa','tyaraity','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7114,0,NULL,'wob','wè northern','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7115,0,NULL,'woc','wogeo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7116,0,NULL,'wod','wolani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7117,0,NULL,'woe','woleaian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7118,0,NULL,'wof','gambian wolof','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7119,0,NULL,'wog','wogamusin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7120,0,NULL,'woi','kamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7121,0,NULL,'wok','longto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7122,0,NULL,'wom','wom (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7123,0,NULL,'won','wongo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7124,0,NULL,'woo','manombai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7125,0,NULL,'wor','woria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7126,0,NULL,'wos','hanga hundi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7127,0,NULL,'wow','wawonii','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7128,0,NULL,'woy','weyto','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7129,0,NULL,'wpc','maco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7130,0,NULL,'wra','warapu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7131,0,NULL,'wrb','warluwara','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7132,0,NULL,'wrd','warduji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7133,0,NULL,'wrg','warungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7134,0,NULL,'wrh','wiradhuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7135,0,NULL,'wri','wariyangga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7136,0,NULL,'wrl','warlmanpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7137,0,NULL,'wrm','warumungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7138,0,NULL,'wrn','warnang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7139,0,NULL,'wrp','waropen','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7140,0,NULL,'wrr','wardaman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7141,0,NULL,'wrs','waris','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7142,0,NULL,'wru','waru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7143,0,NULL,'wrv','waruna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7144,0,NULL,'wrw','gugu warra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7145,0,NULL,'wrx','wae rana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7146,0,NULL,'wry','merwari','1248825600',NULL,NULL,NULL,NULL,'mwr',NULL,NULL); +INSERT INTO "iana_records" VALUES(7147,0,NULL,'wrz','waray (australia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7148,0,NULL,'wsa','warembori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7149,0,NULL,'wsi','wusi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7150,0,NULL,'wsk','waskia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7151,0,NULL,'wsr','owenia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7152,0,NULL,'wss','wasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7153,0,NULL,'wsu','wasu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7154,0,NULL,'wsv','wotapuri-katarqalai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7155,0,NULL,'wtf','dumpu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7156,0,NULL,'wti','berta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7157,0,NULL,'wtk','watakataui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7158,0,NULL,'wtm','mewati','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7159,0,NULL,'wtw','wotu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7160,0,NULL,'wua','wikngenchera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7161,0,NULL,'wub','wunambal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7162,0,NULL,'wud','wudu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7163,0,NULL,'wuh','wutunhua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7164,0,NULL,'wul','silimo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7165,0,NULL,'wum','wumbvu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7166,0,NULL,'wun','bungu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7167,0,NULL,'wur','wurrugu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7168,0,NULL,'wut','wutung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7169,0,NULL,'wuu','wu chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7170,0,NULL,'wuv','wuvulu-aua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7171,0,NULL,'wux','wulna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7172,0,NULL,'wuy','wauyai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7173,0,NULL,'wwa','waama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7174,0,NULL,'wwo','dorig','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7174,0,NULL,'wwo','wetamut','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7175,0,NULL,'wwr','warrwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7176,0,NULL,'www','wawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7177,0,NULL,'wxa','waxianghua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7178,0,NULL,'wya','wyandot','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7179,0,NULL,'wyb','wangaaybuwan-ngiyambaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7180,0,NULL,'wym','wymysorys','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7181,0,NULL,'wyr','wayoró','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7182,0,NULL,'wyy','western fijian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7183,0,NULL,'xaa','andalusian arabic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7184,0,NULL,'xab','sambe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7185,0,NULL,'xac','kachari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7186,0,NULL,'xad','adai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7187,0,NULL,'xae','aequian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7188,0,NULL,'xag','aghwan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7189,0,NULL,'xai','kaimbé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7190,0,NULL,'xal','kalmyk','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7190,0,NULL,'xal','oirat','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7191,0,NULL,'xam','/xam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7192,0,NULL,'xan','xamtanga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7193,0,NULL,'xao','khao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7194,0,NULL,'xap','apalachee','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7195,0,NULL,'xaq','aquitanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7196,0,NULL,'xar','karami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7197,0,NULL,'xas','kamas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7198,0,NULL,'xat','katawixi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7199,0,NULL,'xau','kauwera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7200,0,NULL,'xav','xavánte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7201,0,NULL,'xaw','kawaiisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7202,0,NULL,'xay','kayan mahakam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7203,0,NULL,'xba','kamba (brazil)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7204,0,NULL,'xbb','lower burdekin','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7205,0,NULL,'xbc','bactrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7206,0,NULL,'xbi','kombio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7207,0,NULL,'xbm','middle breton','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7208,0,NULL,'xbn','kenaboi','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7209,0,NULL,'xbo','bolgarian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7210,0,NULL,'xbr','kambera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7211,0,NULL,'xbw','kambiwá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7212,0,NULL,'xbx','kabixí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7213,0,NULL,'xcb','cumbric','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7214,0,NULL,'xcc','camunic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7215,0,NULL,'xce','celtiberian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7216,0,NULL,'xcg','cisalpine gaulish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7217,0,NULL,'xch','chemakum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7217,0,NULL,'xch','chimakum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7218,0,NULL,'xcl','classical armenian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7219,0,NULL,'xcm','comecrudo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7220,0,NULL,'xcn','cotoname','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7221,0,NULL,'xco','chorasmian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7222,0,NULL,'xcr','carian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7223,0,NULL,'xct','classical tibetan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7224,0,NULL,'xcu','curonian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7225,0,NULL,'xcv','chuvantsy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7226,0,NULL,'xcw','coahuilteco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7227,0,NULL,'xcy','cayuse','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7228,0,NULL,'xdc','dacian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7229,0,NULL,'xdm','edomite','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7230,0,NULL,'xdy','malayic dayak','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7231,0,NULL,'xeb','eblan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7232,0,NULL,'xed','hdi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7233,0,NULL,'xeg','//xegwi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7234,0,NULL,'xel','kelo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7235,0,NULL,'xem','kembayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7236,0,NULL,'xep','epi-olmec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7237,0,NULL,'xer','xerénte','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7238,0,NULL,'xes','kesawai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7239,0,NULL,'xet','xetá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7240,0,NULL,'xeu','keoru-ahia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7241,0,NULL,'xfa','faliscan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7242,0,NULL,'xga','galatian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7243,0,NULL,'xgf','gabrielino-fernandeño','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7244,0,NULL,'xgl','galindan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7245,0,NULL,'xgn','mongolian languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7246,0,NULL,'xgr','garza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7247,0,NULL,'xha','harami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7248,0,NULL,'xhc','hunnic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7249,0,NULL,'xhd','hadrami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7250,0,NULL,'xhe','khetrani','1248825600',NULL,NULL,NULL,NULL,'lah',NULL,NULL); +INSERT INTO "iana_records" VALUES(7251,0,NULL,'xhr','hernican','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7252,0,NULL,'xht','hattic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7253,0,NULL,'xhu','hurrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7254,0,NULL,'xhv','khua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7255,0,NULL,'xia','xiandao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7256,0,NULL,'xib','iberian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7257,0,NULL,'xii','xiri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7258,0,NULL,'xil','illyrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7259,0,NULL,'xin','xinca','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7260,0,NULL,'xip','xipináwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7261,0,NULL,'xir','xiriâna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7262,0,NULL,'xiv','indus valley language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7263,0,NULL,'xiy','xipaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7264,0,NULL,'xka','kalkoti','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7265,0,NULL,'xkb','northern nago','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7266,0,NULL,'xkc','kho''ini','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7267,0,NULL,'xkd','mendalam kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7268,0,NULL,'xke','kereho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7269,0,NULL,'xkf','khengkha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7270,0,NULL,'xkg','kagoro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7271,0,NULL,'xkh','karahawyana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7272,0,NULL,'xki','kenyan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7273,0,NULL,'xkj','kajali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7274,0,NULL,'xkk','kaco''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7275,0,NULL,'xkl','mainstream kenyah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7276,0,NULL,'xkn','kayan river kayan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7277,0,NULL,'xko','kiorr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7278,0,NULL,'xkp','kabatei','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7279,0,NULL,'xkq','koroni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7280,0,NULL,'xkr','xakriabá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7281,0,NULL,'xks','kumbewaha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7282,0,NULL,'xkt','kantosi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7283,0,NULL,'xku','kaamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7284,0,NULL,'xkv','kgalagadi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7285,0,NULL,'xkw','kembra','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7286,0,NULL,'xkx','karore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7287,0,NULL,'xky','uma'' lasan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7288,0,NULL,'xkz','kurtokha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7289,0,NULL,'xla','kamula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7290,0,NULL,'xlb','loup b','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7291,0,NULL,'xlc','lycian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7292,0,NULL,'xld','lydian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7293,0,NULL,'xle','lemnian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7294,0,NULL,'xlg','ligurian (ancient)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7295,0,NULL,'xli','liburnian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7296,0,NULL,'xln','alanic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7297,0,NULL,'xlo','loup a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7298,0,NULL,'xlp','lepontic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7299,0,NULL,'xls','lusitanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7300,0,NULL,'xlu','cuneiform luwian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7301,0,NULL,'xly','elymian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7302,0,NULL,'xma','mushungulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7303,0,NULL,'xmb','mbonga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7304,0,NULL,'xmc','makhuwa-marrevone','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7305,0,NULL,'xmd','mbedam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7306,0,NULL,'xme','median','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7307,0,NULL,'xmf','mingrelian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7308,0,NULL,'xmg','mengaka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7309,0,NULL,'xmh','kuku-muminh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7310,0,NULL,'xmj','majera','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7311,0,NULL,'xmk','ancient macedonian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7312,0,NULL,'xml','malaysian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7313,0,NULL,'xmm','manado malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7314,0,NULL,'xmn','manichaean middle persian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7315,0,NULL,'xmo','morerebi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7316,0,NULL,'xmp','kuku-mu''inh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7317,0,NULL,'xmq','kuku-mangk','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7318,0,NULL,'xmr','meroitic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7319,0,NULL,'xms','moroccan sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7320,0,NULL,'xmt','matbat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7321,0,NULL,'xmu','kamu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7322,0,NULL,'xmv','antankarana malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(7323,0,NULL,'xmw','tsimihety malagasy','1248825600',NULL,NULL,NULL,NULL,'mg',NULL,NULL); +INSERT INTO "iana_records" VALUES(7324,0,NULL,'xmx','maden','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7325,0,NULL,'xmy','mayaguduna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7326,0,NULL,'xmz','mori bawah','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7327,0,NULL,'xna','ancient north arabian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7328,0,NULL,'xnb','kanakanabu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7329,0,NULL,'xnd','na-dene languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7330,0,NULL,'xng','middle mongolian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7331,0,NULL,'xnh','kuanhua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7332,0,NULL,'xnn','northern kankanay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7333,0,NULL,'xno','anglo-norman','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7334,0,NULL,'xnr','kangri','1248825600',NULL,NULL,NULL,NULL,'doi',NULL,NULL); +INSERT INTO "iana_records" VALUES(7335,0,NULL,'xns','kanashi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7336,0,NULL,'xnt','narragansett','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7337,0,NULL,'xoc','o''chi''chi''','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7338,0,NULL,'xod','kokoda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7339,0,NULL,'xog','soga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7340,0,NULL,'xoi','kominimung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7341,0,NULL,'xok','xokleng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7342,0,NULL,'xom','komo (sudan)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7343,0,NULL,'xon','konkomba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7344,0,NULL,'xoo','xukurú','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7345,0,NULL,'xop','kopar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7346,0,NULL,'xor','korubo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7347,0,NULL,'xow','kowaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7348,0,NULL,'xpc','pecheneg','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7349,0,NULL,'xpe','liberia kpelle','1248825600',NULL,NULL,NULL,NULL,'kpe',NULL,NULL); +INSERT INTO "iana_records" VALUES(7350,0,NULL,'xpg','phrygian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7351,0,NULL,'xpi','pictish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7352,0,NULL,'xpk','kulina pano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7353,0,NULL,'xpm','pumpokol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7354,0,NULL,'xpn','kapinawá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7355,0,NULL,'xpo','pochutec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7356,0,NULL,'xpp','puyo-paekche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7357,0,NULL,'xpq','mohegan-pequot','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7358,0,NULL,'xpr','parthian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7359,0,NULL,'xps','pisidian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7360,0,NULL,'xpu','punic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7361,0,NULL,'xpy','puyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7362,0,NULL,'xqa','karakhanid','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7363,0,NULL,'xqt','qatabanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7364,0,NULL,'xra','krahô','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7365,0,NULL,'xrb','eastern karaboro','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7366,0,NULL,'xre','kreye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7367,0,NULL,'xri','krikati-timbira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7368,0,NULL,'xrm','armazic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7369,0,NULL,'xrn','arin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7370,0,NULL,'xrr','raetic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7371,0,NULL,'xrt','aranama-tamique','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7372,0,NULL,'xru','marriammu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7373,0,NULL,'xrw','karawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7374,0,NULL,'xsa','sabaean','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7375,0,NULL,'xsb','tinà sambal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7376,0,NULL,'xsc','scythian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7377,0,NULL,'xsd','sidetic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7378,0,NULL,'xse','sempan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7379,0,NULL,'xsh','shamang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7380,0,NULL,'xsi','sio','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7381,0,NULL,'xsj','subi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7382,0,NULL,'xsl','south slavey','1248825600',NULL,NULL,NULL,NULL,'den',NULL,NULL); +INSERT INTO "iana_records" VALUES(7383,0,NULL,'xsm','kasem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7384,0,NULL,'xsn','sanga (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7385,0,NULL,'xso','solano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7386,0,NULL,'xsp','silopi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7387,0,NULL,'xsq','makhuwa-saka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7388,0,NULL,'xsr','sherpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7389,0,NULL,'xss','assan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7390,0,NULL,'xsu','sanumá','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7391,0,NULL,'xsv','sudovian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7392,0,NULL,'xsy','saisiyat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7393,0,NULL,'xta','alcozauca mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7394,0,NULL,'xtb','chazumba mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7395,0,NULL,'xtc','katcha-kadugli-miri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7396,0,NULL,'xtd','diuxi-tilantongo mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7397,0,NULL,'xte','ketengban','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7398,0,NULL,'xtg','transalpine gaulish','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7399,0,NULL,'xti','sinicahua mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7400,0,NULL,'xtj','san juan teita mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7401,0,NULL,'xtl','tijaltepec mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7402,0,NULL,'xtm','magdalena peñasco mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7403,0,NULL,'xtn','northern tlaxiaco mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7404,0,NULL,'xto','tokharian a','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7405,0,NULL,'xtp','san miguel piedras mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7406,0,NULL,'xtq','tumshuqese','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7407,0,NULL,'xtr','early tripuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7408,0,NULL,'xts','sindihui mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7409,0,NULL,'xtt','tacahua mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7410,0,NULL,'xtu','cuyamecalco mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7411,0,NULL,'xtw','tawandê','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7412,0,NULL,'xty','yoloxochitl mixtec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7413,0,NULL,'xtz','tasmanian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7414,0,NULL,'xua','alu kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7415,0,NULL,'xub','betta kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7416,0,NULL,'xug','kunigami','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7417,0,NULL,'xuj','jennu kurumba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7418,0,NULL,'xum','umbrian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7419,0,NULL,'xuo','kuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7420,0,NULL,'xup','upper umpqua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7421,0,NULL,'xur','urartian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7422,0,NULL,'xut','kuthant','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7423,0,NULL,'xuu','kxoe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7424,0,NULL,'xve','venetic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7425,0,NULL,'xvi','kamviri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7426,0,NULL,'xvn','vandalic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7427,0,NULL,'xvo','volscian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7428,0,NULL,'xvs','vestinian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7429,0,NULL,'xwa','kwaza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7430,0,NULL,'xwc','woccon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7431,0,NULL,'xwe','xwela gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7432,0,NULL,'xwg','kwegu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7433,0,NULL,'xwl','western xwla gbe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7434,0,NULL,'xwo','written oirat','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7435,0,NULL,'xwr','kwerba mamberamo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7436,0,NULL,'xxb','boro (ghana)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7437,0,NULL,'xxk','ke''o','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7438,0,NULL,'xxr','koropó','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7439,0,NULL,'xxt','tambora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7440,0,NULL,'xyl','yalakalore','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7441,0,NULL,'xzh','zhang-zhung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7442,0,NULL,'xzm','zemgalian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7443,0,NULL,'xzp','ancient zapotec','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7444,0,NULL,'yaa','yaminahua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7445,0,NULL,'yab','yuhup','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7446,0,NULL,'yac','pass valley yali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7447,0,NULL,'yad','yagua','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7448,0,NULL,'yae','pumé','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7449,0,NULL,'yaf','yaka (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7450,0,NULL,'yag','yámana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7451,0,NULL,'yah','yazgulyam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7452,0,NULL,'yai','yagnobi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7453,0,NULL,'yaj','banda-yangere','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7454,0,NULL,'yak','yakama','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7455,0,NULL,'yal','yalunka','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7456,0,NULL,'yam','yamba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7457,0,NULL,'yan','mayangna','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7458,0,NULL,'yao','yao','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7459,0,NULL,'yap','yapese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7460,0,NULL,'yaq','yaqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7461,0,NULL,'yar','yabarana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7462,0,NULL,'yas','nugunu (cameroon)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7463,0,NULL,'yat','yambeta','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7464,0,NULL,'yau','yuwana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7465,0,NULL,'yav','yangben','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7466,0,NULL,'yaw','yawalapití','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7467,0,NULL,'yax','yauma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7468,0,NULL,'yay','agwagwune','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7469,0,NULL,'yaz','lokaa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7470,0,NULL,'yba','yala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7471,0,NULL,'ybb','yemba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7472,0,NULL,'ybd','yangbye','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7473,0,NULL,'ybe','west yugur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7474,0,NULL,'ybh','yakha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7475,0,NULL,'ybi','yamphu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7476,0,NULL,'ybj','hasha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7477,0,NULL,'ybk','bokha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7478,0,NULL,'ybl','yukuben','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7479,0,NULL,'ybm','yaben','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7480,0,NULL,'ybn','yabaâna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7481,0,NULL,'ybo','yabong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7482,0,NULL,'ybx','yawiyo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7483,0,NULL,'yby','yaweyuha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7484,0,NULL,'ych','chesu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7485,0,NULL,'ycl','lolopo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7486,0,NULL,'ycn','yucuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7487,0,NULL,'ycp','chepya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7488,0,NULL,'ydd','eastern yiddish','1248825600',NULL,NULL,NULL,NULL,'yi',NULL,NULL); +INSERT INTO "iana_records" VALUES(7489,0,NULL,'yde','yangum dey','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7490,0,NULL,'ydg','yidgha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7491,0,NULL,'ydk','yoidik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7492,0,NULL,'yds','yiddish sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7493,0,NULL,'yea','ravula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7494,0,NULL,'yec','yeniche','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7495,0,NULL,'yee','yimas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7496,0,NULL,'yei','yeni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7497,0,NULL,'yej','yevanic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7498,0,NULL,'yel','yela','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7499,0,NULL,'yen','yendang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7500,0,NULL,'yer','tarok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7501,0,NULL,'yes','yeskwa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7502,0,NULL,'yet','yetfa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7503,0,NULL,'yeu','yerukula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7504,0,NULL,'yev','yapunda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7505,0,NULL,'yey','yeyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7506,0,NULL,'ygl','yangum gel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7507,0,NULL,'ygm','yagomi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7508,0,NULL,'ygp','gepo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7509,0,NULL,'ygr','yagaria','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7510,0,NULL,'ygw','yagwoia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7511,0,NULL,'yha','baha buyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7512,0,NULL,'yhd','judeo-iraqi arabic','1248825600',NULL,NULL,NULL,NULL,'jrb',NULL,NULL); +INSERT INTO "iana_records" VALUES(7513,0,NULL,'yhl','hlepho phowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7514,0,NULL,'yia','yinggarda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7515,0,NULL,'yif','ache','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7516,0,NULL,'yig','wusa nasu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7517,0,NULL,'yih','western yiddish','1248825600',NULL,NULL,NULL,NULL,'yi',NULL,NULL); +INSERT INTO "iana_records" VALUES(7518,0,NULL,'yii','yidiny','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7519,0,NULL,'yij','yindjibarndi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7520,0,NULL,'yik','dongshanba lalo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7521,0,NULL,'yil','yindjilandji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7522,0,NULL,'yim','yimchungru naga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7523,0,NULL,'yin','yinchia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7524,0,NULL,'yip','pholo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7525,0,NULL,'yiq','miqie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7526,0,NULL,'yir','north awyu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7527,0,NULL,'yis','yis','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7528,0,NULL,'yit','eastern lalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7529,0,NULL,'yiu','awu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7530,0,NULL,'yiv','northern nisu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7531,0,NULL,'yix','axi yi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7532,0,NULL,'yiy','yir yoront','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7533,0,NULL,'yiz','azhe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7534,0,NULL,'yka','yakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7535,0,NULL,'ykg','northern yukaghir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7536,0,NULL,'yki','yoke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7537,0,NULL,'ykk','yakaikeke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7538,0,NULL,'ykl','khlula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7539,0,NULL,'ykm','kap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7540,0,NULL,'yko','yasa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7541,0,NULL,'ykr','yekora','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7542,0,NULL,'ykt','kathu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7543,0,NULL,'yky','yakoma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7544,0,NULL,'yla','yaul','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7545,0,NULL,'ylb','yaleba','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7546,0,NULL,'yle','yele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7547,0,NULL,'ylg','yelogu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7548,0,NULL,'yli','angguruk yali','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7549,0,NULL,'yll','yil','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7550,0,NULL,'ylm','limi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7551,0,NULL,'yln','langnian buyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7552,0,NULL,'ylo','naluo yi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7553,0,NULL,'ylr','yalarnnga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7554,0,NULL,'ylu','aribwaung','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7555,0,NULL,'yly','nyâlayu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7556,0,NULL,'yma','yamphe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7557,0,NULL,'ymb','yambes','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7558,0,NULL,'ymc','southern muji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7559,0,NULL,'ymd','muda','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7560,0,NULL,'yme','yameo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7561,0,NULL,'ymg','yamongeri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7562,0,NULL,'ymh','mili','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7563,0,NULL,'ymi','moji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7564,0,NULL,'ymk','makwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7565,0,NULL,'yml','iamalele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7566,0,NULL,'ymm','maay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7567,0,NULL,'ymn','sunum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7567,0,NULL,'ymn','yamna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7568,0,NULL,'ymo','yangum mon','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7569,0,NULL,'ymp','yamap','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7570,0,NULL,'ymq','qila muji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7571,0,NULL,'ymr','malasar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7572,0,NULL,'yms','mysian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7573,0,NULL,'ymt','mator-taygi-karagas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7574,0,NULL,'ymx','northern muji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7575,0,NULL,'ymz','muzi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7576,0,NULL,'yna','aluo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7577,0,NULL,'ynd','yandruwandha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7578,0,NULL,'yne','lang''e','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7579,0,NULL,'yng','yango','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7580,0,NULL,'ynh','yangho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7581,0,NULL,'ynk','naukan yupik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7582,0,NULL,'ynl','yangulam','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7583,0,NULL,'ynn','yana','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7584,0,NULL,'yno','yong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7585,0,NULL,'yns','yansi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7586,0,NULL,'ynu','yahuna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7587,0,NULL,'yob','yoba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7588,0,NULL,'yog','yogad','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7589,0,NULL,'yoi','yonaguni','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7590,0,NULL,'yok','yokuts','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7591,0,NULL,'yol','yola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7592,0,NULL,'yom','yombe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7593,0,NULL,'yon','yonggom','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7594,0,NULL,'yos','yos','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7595,0,NULL,'yox','yoron','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7596,0,NULL,'yoy','yoy','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7597,0,NULL,'ypa','phala','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7598,0,NULL,'ypb','labo phowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7599,0,NULL,'ypg','phola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7600,0,NULL,'yph','phupha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7601,0,NULL,'ypk','yupik languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7602,0,NULL,'ypm','phuma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7603,0,NULL,'ypn','ani phowa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7604,0,NULL,'ypo','alo phola','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7605,0,NULL,'ypp','phupa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7606,0,NULL,'ypz','phuza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7607,0,NULL,'yra','yerakai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7608,0,NULL,'yrb','yareba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7609,0,NULL,'yre','yaouré','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7610,0,NULL,'yri','yarí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7611,0,NULL,'yrk','nenets','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7612,0,NULL,'yrl','nhengatu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7613,0,NULL,'yrn','yerong','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7614,0,NULL,'yrs','yarsun','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7615,0,NULL,'yrw','yarawata','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7616,0,NULL,'ysc','yassic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7617,0,NULL,'ysd','samatao','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7618,0,NULL,'ysl','yugoslavian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7619,0,NULL,'ysn','sani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7620,0,NULL,'yso','nisi (china)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7621,0,NULL,'ysp','southern lolopo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7622,0,NULL,'ysr','sirenik yupik','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7623,0,NULL,'yss','yessan-mayo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7624,0,NULL,'ysy','sanie','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7625,0,NULL,'yta','talu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7626,0,NULL,'ytl','tanglang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7627,0,NULL,'ytp','thopho','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7628,0,NULL,'ytw','yout wam','1268265600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7629,0,NULL,'yua','yucatec maya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7629,0,NULL,'yua','yucateco','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7630,0,NULL,'yub','yugambal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7631,0,NULL,'yuc','yuchi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7632,0,NULL,'yud','judeo-tripolitanian arabic','1248825600',NULL,NULL,NULL,NULL,'jrb',NULL,NULL); +INSERT INTO "iana_records" VALUES(7633,0,NULL,'yue','yue chinese','1248825600',NULL,NULL,NULL,NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7634,0,NULL,'yuf','havasupai-walapai-yavapai','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7635,0,NULL,'yug','yug','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7636,0,NULL,'yui','yurutí','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7637,0,NULL,'yuj','karkar-yuri','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7638,0,NULL,'yuk','yuki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7639,0,NULL,'yul','yulu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7640,0,NULL,'yum','quechan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7641,0,NULL,'yun','bena (nigeria)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7642,0,NULL,'yup','yukpa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7643,0,NULL,'yuq','yuqui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7644,0,NULL,'yur','yurok','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7645,0,NULL,'yut','yopno','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7646,0,NULL,'yuu','yugh','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7647,0,NULL,'yuw','yau (morobe province)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7648,0,NULL,'yux','southern yukaghir','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7649,0,NULL,'yuy','east yugur','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7650,0,NULL,'yuz','yuracare','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7651,0,NULL,'yva','yawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7652,0,NULL,'yvt','yavitero','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7653,0,NULL,'ywa','kalou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7654,0,NULL,'ywl','western lalu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7655,0,NULL,'ywn','yawanawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7656,0,NULL,'ywq','wuding-luquan yi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7657,0,NULL,'ywr','yawuru','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7658,0,NULL,'ywt','xishanba lalo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7659,0,NULL,'ywu','wumeng nasu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7660,0,NULL,'yww','yawarawarga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7661,0,NULL,'yyu','yau (sandaun province)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7662,0,NULL,'yyz','ayizi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7663,0,NULL,'yzg','e''ma buyang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7664,0,NULL,'yzk','zokhuo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7665,0,NULL,'zaa','sierra de juárez zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7666,0,NULL,'zab','san juan guelavía zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7667,0,NULL,'zac','ocotlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7668,0,NULL,'zad','cajonos zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7669,0,NULL,'zae','yareni zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7670,0,NULL,'zaf','ayoquesco zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7671,0,NULL,'zag','zaghawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7672,0,NULL,'zah','zangwal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7673,0,NULL,'zai','isthmus zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7674,0,NULL,'zaj','zaramo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7675,0,NULL,'zak','zanaki','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7676,0,NULL,'zal','zauzou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7677,0,NULL,'zam','miahuatlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7678,0,NULL,'zao','ozolotepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7679,0,NULL,'zap','zapotec','1129420800',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7680,0,NULL,'zaq','aloápam zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7681,0,NULL,'zar','rincón zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7682,0,NULL,'zas','santo domingo albarradas zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7683,0,NULL,'zat','tabaa zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7684,0,NULL,'zau','zangskari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7685,0,NULL,'zav','yatzachi zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7686,0,NULL,'zaw','mitla zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7687,0,NULL,'zax','xadani zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7688,0,NULL,'zay','zayse-zergulla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7688,0,NULL,'zay','zaysete','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7689,0,NULL,'zaz','zari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7690,0,NULL,'zbc','central berawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7691,0,NULL,'zbe','east berawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7692,0,NULL,'zbl','bliss','1187654400',NULL,NULL,NULL,'blis',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7692,0,NULL,'zbl','blissymbolics','1187654400',NULL,NULL,NULL,'blis',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7692,0,NULL,'zbl','blissymbols','1187654400',NULL,NULL,NULL,'blis',NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7693,0,NULL,'zbt','batui','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7694,0,NULL,'zbw','west berawan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7695,0,NULL,'zca','coatecas altas zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7696,0,NULL,'zch','central hongshuihe zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7697,0,NULL,'zdj','ngazidja comorian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7698,0,NULL,'zea','zeeuws','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7699,0,NULL,'zeg','zenag','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7700,0,NULL,'zeh','eastern hongshuihe zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7701,0,NULL,'zen','zenaga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7702,0,NULL,'zga','kinga','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7703,0,NULL,'zgb','guibei zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7704,0,NULL,'zgm','minz zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7705,0,NULL,'zgn','guibian zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7706,0,NULL,'zgr','magori','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7707,0,NULL,'zhb','zhaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7708,0,NULL,'zhd','dai zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7709,0,NULL,'zhi','zhire','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7710,0,NULL,'zhn','nong zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7711,0,NULL,'zhw','zhoa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7712,0,NULL,'zhx','chinese (family)','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7713,0,NULL,'zia','zia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7714,0,NULL,'zib','zimbabwe sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7715,0,NULL,'zik','zimakani','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7716,0,NULL,'zim','mesme','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7717,0,NULL,'zin','zinza','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7718,0,NULL,'zir','ziriya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7719,0,NULL,'ziw','zigula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7720,0,NULL,'ziz','zizilivakan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7721,0,NULL,'zka','kaimbulawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7722,0,NULL,'zkb','koibal','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7723,0,NULL,'zkg','koguryo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7724,0,NULL,'zkh','khorezmian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7725,0,NULL,'zkk','karankawa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7726,0,NULL,'zko','kott','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7727,0,NULL,'zkp','são paulo kaingáng','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7728,0,NULL,'zkr','zakhring','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7729,0,NULL,'zkt','kitan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7730,0,NULL,'zku','kaurna','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7731,0,NULL,'zkv','krevinian','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7732,0,NULL,'zkz','khazar','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7733,0,NULL,'zle','east slavic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7734,0,NULL,'zlj','liujiang zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7735,0,NULL,'zlm','malay (individual language)','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7736,0,NULL,'zln','lianshan zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7737,0,NULL,'zlq','liuqian zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7738,0,NULL,'zls','south slavic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7739,0,NULL,'zlw','west slavic languages','1248825600',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7740,0,NULL,'zma','manda (australia)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7741,0,NULL,'zmb','zimba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7742,0,NULL,'zmc','margany','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7743,0,NULL,'zmd','maridan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7744,0,NULL,'zme','mangerr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7745,0,NULL,'zmf','mfinu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7746,0,NULL,'zmg','marti ke','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7747,0,NULL,'zmh','makolkol','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7748,0,NULL,'zmi','negeri sembilan malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7749,0,NULL,'zmj','maridjabin','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7750,0,NULL,'zmk','mandandanyi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7751,0,NULL,'zml','madngele','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7752,0,NULL,'zmm','marimanindji','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7753,0,NULL,'zmn','mbangwe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7754,0,NULL,'zmo','molo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7755,0,NULL,'zmp','mpuono','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7756,0,NULL,'zmq','mituku','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7757,0,NULL,'zmr','maranunggu','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7758,0,NULL,'zms','mbesa','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7759,0,NULL,'zmt','maringarr','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7760,0,NULL,'zmu','muruwari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7761,0,NULL,'zmv','mbariman-gudhinma','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7762,0,NULL,'zmw','mbo (democratic republic of congo)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7763,0,NULL,'zmx','bomitaba','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7764,0,NULL,'zmy','mariyedi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7765,0,NULL,'zmz','mbandja','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7766,0,NULL,'zna','zan gula','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7767,0,NULL,'znd','zande languages','1129420800',NULL,NULL,NULL,NULL,NULL,'collection',NULL); +INSERT INTO "iana_records" VALUES(7768,0,NULL,'zne','zande (individual language)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7769,0,NULL,'zng','mang','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7770,0,NULL,'znk','manangkari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7771,0,NULL,'zns','mangas','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7772,0,NULL,'zoc','copainalá zoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7773,0,NULL,'zoh','chimalapa zoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7774,0,NULL,'zom','zou','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7775,0,NULL,'zoo','asunción mixtepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7776,0,NULL,'zoq','tabasco zoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7777,0,NULL,'zor','rayón zoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7778,0,NULL,'zos','francisco león zoque','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7779,0,NULL,'zpa','lachiguiri zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7780,0,NULL,'zpb','yautepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7781,0,NULL,'zpc','choapan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7782,0,NULL,'zpd','southeastern ixtlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7783,0,NULL,'zpe','petapa zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7784,0,NULL,'zpf','san pedro quiatoni zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7785,0,NULL,'zpg','guevea de humboldt zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7786,0,NULL,'zph','totomachapan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7787,0,NULL,'zpi','santa maría quiegolani zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7788,0,NULL,'zpj','quiavicuzas zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7789,0,NULL,'zpk','tlacolulita zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7790,0,NULL,'zpl','lachixío zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7791,0,NULL,'zpm','mixtepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7792,0,NULL,'zpn','santa inés yatzechi zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7793,0,NULL,'zpo','amatlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7794,0,NULL,'zpp','el alto zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7795,0,NULL,'zpq','zoogocho zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7796,0,NULL,'zpr','santiago xanica zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7797,0,NULL,'zps','coatlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7798,0,NULL,'zpt','san vicente coatlán zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7799,0,NULL,'zpu','yalálag zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7800,0,NULL,'zpv','chichicapan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7801,0,NULL,'zpw','zaniza zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7802,0,NULL,'zpx','san baltazar loxicha zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7803,0,NULL,'zpy','mazaltepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7804,0,NULL,'zpz','texmelucan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7805,0,NULL,'zqe','qiubei zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7806,0,NULL,'zra','kara (korea)','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7807,0,NULL,'zrg','mirgan','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7808,0,NULL,'zrn','zerenkel','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7809,0,NULL,'zro','záparo','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7810,0,NULL,'zrp','zarphatic','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7811,0,NULL,'zrs','mairasi','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7812,0,NULL,'zsa','sarasira','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7813,0,NULL,'zsk','kaskean','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7814,0,NULL,'zsl','zambian sign language','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7815,0,NULL,'zsm','standard malay','1248825600',NULL,NULL,NULL,NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7816,0,NULL,'zsr','southern rincon zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7817,0,NULL,'zsu','sukurum','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7818,0,NULL,'zte','elotepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7819,0,NULL,'ztg','xanaguía zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7820,0,NULL,'ztl','lapaguía-guivini zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7821,0,NULL,'ztm','san agustín mixtepec zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7822,0,NULL,'ztn','santa catarina albarradas zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7823,0,NULL,'ztp','loxicha zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7824,0,NULL,'ztq','quioquitani-quierí zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7825,0,NULL,'zts','tilquiapan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7826,0,NULL,'ztt','tejalapan zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7827,0,NULL,'ztu','güilá zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7828,0,NULL,'ztx','zaachila zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7829,0,NULL,'zty','yatee zapotec','1248825600',NULL,NULL,NULL,NULL,'zap',NULL,NULL); +INSERT INTO "iana_records" VALUES(7830,0,NULL,'zua','zeem','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7831,0,NULL,'zuh','tokano','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7832,0,NULL,'zum','kumzari','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7833,0,NULL,'zun','zuni','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7834,0,NULL,'zuy','zumaya','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7835,0,NULL,'zwa','zay','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7836,0,NULL,'zxx','no linguistic content','1141776000',NULL,NULL,NULL,NULL,NULL,'special',NULL); +INSERT INTO "iana_records" VALUES(7836,0,NULL,'zxx','not applicable','1141776000',NULL,NULL,NULL,NULL,NULL,'special',NULL); +INSERT INTO "iana_records" VALUES(7837,0,NULL,'zyb','yongbei zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7838,0,NULL,'zyg','yang zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7839,0,NULL,'zyj','youjiang zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7840,0,NULL,'zyn','yongnan zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7841,0,NULL,'zyp','zyphe','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','dimili','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','dimli (macrolanguage)','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','kirdki','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','kirmanjki (macrolanguage)','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','zaza','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7842,0,NULL,'zza','zazaki','1156377600',NULL,NULL,NULL,NULL,NULL,'macrolanguage',NULL); +INSERT INTO "iana_records" VALUES(7843,6,NULL,'zzj','zuojiang zhuang','1248825600',NULL,NULL,NULL,NULL,'za',NULL,NULL); +INSERT INTO "iana_records" VALUES(7844,6,NULL,'aao','algerian saharan arabic','1248825600',NULL,'aao','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7845,6,NULL,'abh','tajiki arabic','1248825600',NULL,'abh','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7846,6,NULL,'abv','baharna arabic','1248825600',NULL,'abv','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7847,6,NULL,'acm','mesopotamian arabic','1248825600',NULL,'acm','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7848,6,NULL,'acq','ta''izzi-adeni arabic','1248825600',NULL,'acq','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7849,6,NULL,'acw','hijazi arabic','1248825600',NULL,'acw','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7850,6,NULL,'acx','omani arabic','1248825600',NULL,'acx','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7851,6,NULL,'acy','cypriot arabic','1248825600',NULL,'acy','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7852,6,NULL,'adf','dhofari arabic','1248825600',NULL,'adf','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7853,6,NULL,'ads','adamorobe sign language','1248825600',NULL,'ads','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7854,6,NULL,'aeb','tunisian arabic','1248825600',NULL,'aeb','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7855,6,NULL,'aec','saidi arabic','1248825600',NULL,'aec','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7856,6,NULL,'aed','argentine sign language','1248825600',NULL,'aed','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7857,6,NULL,'aen','armenian sign language','1248825600',NULL,'aen','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7858,6,NULL,'afb','gulf arabic','1248825600',NULL,'afb','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7859,6,NULL,'afg','afghan sign language','1248825600',NULL,'afg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7860,6,NULL,'ajp','south levantine arabic','1248825600',NULL,'ajp','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7861,6,NULL,'apc','north levantine arabic','1248825600',NULL,'apc','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7862,6,NULL,'apd','sudanese arabic','1248825600',NULL,'apd','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7863,6,NULL,'arb','standard arabic','1248825600',NULL,'arb','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7864,6,NULL,'arq','algerian arabic','1248825600',NULL,'arq','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7865,6,NULL,'ars','najdi arabic','1248825600',NULL,'ars','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7866,6,NULL,'ary','moroccan arabic','1248825600',NULL,'ary','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7867,6,NULL,'arz','egyptian arabic','1248825600',NULL,'arz','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7868,6,NULL,'ase','american sign language','1248825600',NULL,'ase','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7869,6,NULL,'asf','australian sign language','1248825600',NULL,'asf','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7870,6,NULL,'asp','algerian sign language','1248825600',NULL,'asp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7871,6,NULL,'asq','austrian sign language','1248825600',NULL,'asq','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7872,6,NULL,'asw','australian aborigines sign language','1248825600',NULL,'asw','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7873,6,NULL,'auz','uzbeki arabic','1248825600',NULL,'auz','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7874,6,NULL,'avl','eastern egyptian bedawi arabic','1248825600',NULL,'avl','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7875,6,NULL,'ayh','hadrami arabic','1248825600',NULL,'ayh','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7876,6,NULL,'ayl','libyan arabic','1248825600',NULL,'ayl','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7877,6,NULL,'ayn','sanaani arabic','1248825600',NULL,'ayn','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7878,6,NULL,'ayp','north mesopotamian arabic','1248825600',NULL,'ayp','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7879,6,NULL,'bbz','babalia creole arabic','1248825600',NULL,'bbz','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(7880,6,NULL,'bfi','british sign language','1248825600',NULL,'bfi','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7881,6,NULL,'bfk','ban khor sign language','1248825600',NULL,'bfk','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7882,6,NULL,'bjn','banjar','1248825600',NULL,'bjn','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7883,6,NULL,'bog','bamako sign language','1248825600',NULL,'bog','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7884,6,NULL,'bqn','bulgarian sign language','1248825600',NULL,'bqn','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7885,6,NULL,'bqy','bengkala sign language','1248825600',NULL,'bqy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7886,6,NULL,'btj','bacanese malay','1248825600',NULL,'btj','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7887,6,NULL,'bve','berau malay','1248825600',NULL,'bve','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7888,6,NULL,'bvl','bolivian sign language','1248825600',NULL,'bvl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7889,6,NULL,'bvu','bukit malay','1248825600',NULL,'bvu','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7890,6,NULL,'bzs','brazilian sign language','1248825600',NULL,'bzs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7891,6,NULL,'cdo','min dong chinese','1248825600',NULL,'cdo','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7892,6,NULL,'cds','chadian sign language','1248825600',NULL,'cds','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7893,6,NULL,'cjy','jinyu chinese','1248825600',NULL,'cjy','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7894,6,NULL,'cmn','mandarin chinese','1248825600',NULL,'cmn','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7895,6,NULL,'coa','cocos islands malay','1248825600',NULL,'coa','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7896,6,NULL,'cpx','pu-xian chinese','1248825600',NULL,'cpx','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7897,6,NULL,'csc','catalan sign language','1248825600',NULL,'csc','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7897,6,NULL,'csc','lengua de señas catalana','1248825600',NULL,'csc','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7897,6,NULL,'csc','llengua de signes catalana','1248825600',NULL,'csc','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7898,6,NULL,'csd','chiangmai sign language','1248825600',NULL,'csd','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7899,6,NULL,'cse','czech sign language','1248825600',NULL,'cse','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7900,6,NULL,'csf','cuba sign language','1248825600',NULL,'csf','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7901,6,NULL,'csg','chilean sign language','1248825600',NULL,'csg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7902,6,NULL,'csl','chinese sign language','1248825600',NULL,'csl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7903,6,NULL,'csn','colombian sign language','1248825600',NULL,'csn','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7904,6,NULL,'csq','croatia sign language','1248825600',NULL,'csq','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7905,6,NULL,'csr','costa rican sign language','1248825600',NULL,'csr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7906,6,NULL,'czh','huizhou chinese','1248825600',NULL,'czh','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7907,6,NULL,'czo','min zhong chinese','1248825600',NULL,'czo','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7908,6,NULL,'doq','dominican sign language','1248825600',NULL,'doq','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7909,6,NULL,'dse','dutch sign language','1248825600',NULL,'dse','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7910,6,NULL,'dsl','danish sign language','1248825600',NULL,'dsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7911,6,NULL,'dup','duano','1248825600',NULL,'dup','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7912,6,NULL,'ecs','ecuadorian sign language','1248825600',NULL,'ecs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7913,6,NULL,'esl','egypt sign language','1248825600',NULL,'esl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7914,6,NULL,'esn','salvadoran sign language','1248825600',NULL,'esn','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7915,6,NULL,'eso','estonian sign language','1248825600',NULL,'eso','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7916,6,NULL,'eth','ethiopian sign language','1248825600',NULL,'eth','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7917,6,NULL,'fcs','quebec sign language','1248825600',NULL,'fcs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7918,6,NULL,'fse','finnish sign language','1248825600',NULL,'fse','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7919,6,NULL,'fsl','french sign language','1248825600',NULL,'fsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7920,6,NULL,'fss','finland-swedish sign language','1248825600',NULL,'fss','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7920,6,NULL,'fss','finlandssvenskt teckenspråk','1248825600',NULL,'fss','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7920,6,NULL,'fss','suomenruotsalainen viittomakieli','1248825600',NULL,'fss','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7921,6,NULL,'gan','gan chinese','1248825600',NULL,'gan','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7922,6,NULL,'gom','goan konkani','1248825600',NULL,'gom','kok',NULL,'kok',NULL,NULL); +INSERT INTO "iana_records" VALUES(7923,6,NULL,'gse','ghanaian sign language','1248825600',NULL,'gse','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7924,6,NULL,'gsg','german sign language','1248825600',NULL,'gsg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7925,6,NULL,'gsm','guatemalan sign language','1248825600',NULL,'gsm','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7926,6,NULL,'gss','greek sign language','1248825600',NULL,'gss','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7927,6,NULL,'gus','guinean sign language','1248825600',NULL,'gus','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7928,6,NULL,'hab','hanoi sign language','1248825600',NULL,'hab','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7929,6,NULL,'haf','haiphong sign language','1248825600',NULL,'haf','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7930,6,NULL,'hak','hakka chinese','1248825600',NULL,'hak','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7931,6,NULL,'hds','honduras sign language','1248825600',NULL,'hds','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7932,6,NULL,'hji','haji','1248825600',NULL,'hji','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7933,6,NULL,'hks','heung kong sau yue','1248825600',NULL,'hks','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7933,6,NULL,'hks','hong kong sign language','1248825600',NULL,'hks','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7934,6,NULL,'hos','ho chi minh city sign language','1248825600',NULL,'hos','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7935,6,NULL,'hps','hawai''i pidgin sign language','1248825600',NULL,'hps','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7936,6,NULL,'hsh','hungarian sign language','1248825600',NULL,'hsh','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7937,6,NULL,'hsl','hausa sign language','1248825600',NULL,'hsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7938,6,NULL,'hsn','xiang chinese','1248825600',NULL,'hsn','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7939,6,NULL,'icl','icelandic sign language','1248825600',NULL,'icl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7940,6,NULL,'ils','international sign','1248825600',NULL,'ils','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7941,6,NULL,'inl','indonesian sign language','1248825600',NULL,'inl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7942,6,NULL,'ins','indian sign language','1248825600',NULL,'ins','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7943,6,NULL,'ise','italian sign language','1248825600',NULL,'ise','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7944,6,NULL,'isg','irish sign language','1248825600',NULL,'isg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7945,6,NULL,'isr','israeli sign language','1248825600',NULL,'isr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7946,6,NULL,'jak','jakun','1248825600',NULL,'jak','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7947,6,NULL,'jax','jambi malay','1248825600',NULL,'jax','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7948,6,NULL,'jcs','jamaican country sign language','1248825600',NULL,'jcs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7949,6,NULL,'jhs','jhankot sign language','1248825600',NULL,'jhs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7950,6,NULL,'jls','jamaican sign language','1268265600',NULL,'jls','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7951,6,NULL,'jos','jordanian sign language','1248825600',NULL,'jos','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7952,6,NULL,'jsl','japanese sign language','1248825600',NULL,'jsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7953,6,NULL,'jus','jumla sign language','1248825600',NULL,'jus','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7954,6,NULL,'kgi','selangor sign language','1248825600',NULL,'kgi','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7955,6,NULL,'knn','konkani (individual language)','1248825600',NULL,'knn','kok',NULL,'kok',NULL,NULL); +INSERT INTO "iana_records" VALUES(7956,6,NULL,'kvb','kubu','1248825600',NULL,'kvb','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7957,6,NULL,'kvk','korean sign language','1248825600',NULL,'kvk','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7958,6,NULL,'kvr','kerinci','1248825600',NULL,'kvr','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7959,6,NULL,'kxd','brunei','1248825600',NULL,'kxd','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7960,6,NULL,'lbs','libyan sign language','1248825600',NULL,'lbs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7961,6,NULL,'lce','loncong','1248825600',NULL,'lce','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7962,6,NULL,'lcf','lubu','1248825600',NULL,'lcf','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7963,6,NULL,'liw','col','1248825600',NULL,'liw','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7964,6,NULL,'lls','lithuanian sign language','1248825600',NULL,'lls','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7965,6,NULL,'lsg','lyons sign language','1248825600',NULL,'lsg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7966,6,NULL,'lsl','latvian sign language','1248825600',NULL,'lsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7967,6,NULL,'lso','laos sign language','1248825600',NULL,'lso','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7968,6,NULL,'lsp','lengua de señas panameñas','1248825600',NULL,'lsp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7968,6,NULL,'lsp','panamanian sign language','1248825600',NULL,'lsp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7969,6,NULL,'lst','trinidad and tobago sign language','1248825600',NULL,'lst','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7970,6,NULL,'lsy','mauritian sign language','1268265600',NULL,'lsy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7971,6,NULL,'ltg','latgalian','1268265600',NULL,'ltg','lv',NULL,'lv',NULL,NULL); +INSERT INTO "iana_records" VALUES(7972,6,NULL,'lvs','standard latvian','1268265600',NULL,'lvs','lv',NULL,'lv',NULL,NULL); +INSERT INTO "iana_records" VALUES(7973,6,NULL,'lzh','literary chinese','1248825600',NULL,'lzh','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7974,6,NULL,'max','north moluccan malay','1248825600',NULL,'max','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7975,6,NULL,'mdl','maltese sign language','1248825600',NULL,'mdl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7976,6,NULL,'meo','kedah malay','1248825600',NULL,'meo','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7977,6,NULL,'mfa','pattani malay','1248825600',NULL,'mfa','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7978,6,NULL,'mfb','bangka','1248825600',NULL,'mfb','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7979,6,NULL,'mfs','mexican sign language','1248825600',NULL,'mfs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7980,6,NULL,'min','minangkabau','1248825600',NULL,'min','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7981,6,NULL,'mnp','min bei chinese','1248825600',NULL,'mnp','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7982,6,NULL,'mqg','kota bangun kutai malay','1248825600',NULL,'mqg','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7983,6,NULL,'mre','martha''s vineyard sign language','1248825600',NULL,'mre','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7984,6,NULL,'msd','yucatec maya sign language','1248825600',NULL,'msd','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7985,6,NULL,'msi','sabah malay','1248825600',NULL,'msi','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7986,6,NULL,'msr','mongolian sign language','1248825600',NULL,'msr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7987,6,NULL,'mui','musi','1248825600',NULL,'mui','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(7988,6,NULL,'mzc','madagascar sign language','1248825600',NULL,'mzc','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7989,6,NULL,'mzg','monastic sign language','1248825600',NULL,'mzg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7990,6,NULL,'mzy','mozambican sign language','1248825600',NULL,'mzy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7991,6,NULL,'nan','min nan chinese','1248825600',NULL,'nan','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(7992,6,NULL,'nbs','namibian sign language','1248825600',NULL,'nbs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7993,6,NULL,'ncs','nicaraguan sign language','1248825600',NULL,'ncs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7994,6,NULL,'nsi','nigerian sign language','1248825600',NULL,'nsi','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7995,6,NULL,'nsl','norwegian sign language','1248825600',NULL,'nsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7996,6,NULL,'nsp','nepalese sign language','1248825600',NULL,'nsp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7997,6,NULL,'nsr','maritime sign language','1248825600',NULL,'nsr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7998,6,NULL,'nzs','new zealand sign language','1248825600',NULL,'nzs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(7999,6,NULL,'okl','old kentish sign language','1248825600',NULL,'okl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8000,6,NULL,'orn','orang kanaq','1248825600',NULL,'orn','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8001,6,NULL,'ors','orang seletar','1248825600',NULL,'ors','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8002,6,NULL,'pel','pekal','1248825600',NULL,'pel','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8003,6,NULL,'pga','sudanese creole arabic','1248825600',NULL,'pga','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(8004,6,NULL,'pks','pakistan sign language','1248825600',NULL,'pks','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8005,6,NULL,'prl','peruvian sign language','1248825600',NULL,'prl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8006,6,NULL,'prz','providencia sign language','1248825600',NULL,'prz','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8007,6,NULL,'psc','persian sign language','1248825600',NULL,'psc','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8008,6,NULL,'psd','plains indian sign language','1248825600',NULL,'psd','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8009,6,NULL,'pse','central malay','1248825600',NULL,'pse','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8010,6,NULL,'psg','penang sign language','1248825600',NULL,'psg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8011,6,NULL,'psl','puerto rican sign language','1248825600',NULL,'psl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8012,6,NULL,'pso','polish sign language','1248825600',NULL,'pso','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8013,6,NULL,'psp','philippine sign language','1248825600',NULL,'psp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8014,6,NULL,'psr','portuguese sign language','1248825600',NULL,'psr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8015,6,NULL,'pys','lengua de señas del paraguay','1268265600',NULL,'pys','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8015,6,NULL,'pys','paraguayan sign language','1268265600',NULL,'pys','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8016,6,NULL,'rms','romanian sign language','1248825600',NULL,'rms','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8017,6,NULL,'rsi','rennellese sign language','1248825600',NULL,'rsi','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8018,6,NULL,'rsl','russian sign language','1248825600',NULL,'rsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8019,6,NULL,'sdl','saudi arabian sign language','1248825600',NULL,'sdl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8020,6,NULL,'sfb','french belgian sign language','1248825600',NULL,'sfb','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8020,6,NULL,'sfb','langue des signes de belgique francophone','1248825600',NULL,'sfb','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8021,6,NULL,'sfs','south african sign language','1248825600',NULL,'sfs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8022,6,NULL,'sgg','swiss-german sign language','1248825600',NULL,'sgg','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8023,6,NULL,'sgx','sierra leone sign language','1248825600',NULL,'sgx','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8024,6,NULL,'shu','chadian arabic','1248825600',NULL,'shu','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(8025,6,NULL,'slf','swiss-italian sign language','1248825600',NULL,'slf','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8026,6,NULL,'sls','singapore sign language','1248825600',NULL,'sls','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8027,6,NULL,'sqs','sri lankan sign language','1248825600',NULL,'sqs','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8028,6,NULL,'ssh','shihhi arabic','1248825600',NULL,'ssh','ar',NULL,'ar',NULL,NULL); +INSERT INTO "iana_records" VALUES(8029,6,NULL,'ssp','spanish sign language','1248825600',NULL,'ssp','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8030,6,NULL,'ssr','swiss-french sign language','1248825600',NULL,'ssr','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8031,6,NULL,'svk','slovakian sign language','1248825600',NULL,'svk','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8032,6,NULL,'swc','congo swahili','1248825600',NULL,'swc','sw',NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(8033,6,NULL,'swh','kiswahili','1248825600',NULL,'swh','sw',NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(8033,6,NULL,'swh','swahili (individual language)','1248825600',NULL,'swh','sw',NULL,'sw',NULL,NULL); +INSERT INTO "iana_records" VALUES(8034,6,NULL,'swl','swedish sign language','1248825600',NULL,'swl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8035,6,NULL,'syy','al-sayyid bedouin sign language','1248825600',NULL,'syy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8036,6,NULL,'tmw','temuan','1248825600',NULL,'tmw','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8037,6,NULL,'tse','tunisian sign language','1248825600',NULL,'tse','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8038,6,NULL,'tsm','turkish sign language','1248825600',NULL,'tsm','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8038,6,NULL,'tsm','türk İşaret dili','1248825600',NULL,'tsm','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8039,6,NULL,'tsq','thai sign language','1248825600',NULL,'tsq','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8040,6,NULL,'tss','taiwan sign language','1248825600',NULL,'tss','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8041,6,NULL,'tsy','tebul sign language','1248825600',NULL,'tsy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8042,6,NULL,'tza','tanzanian sign language','1248825600',NULL,'tza','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8043,6,NULL,'ugn','ugandan sign language','1248825600',NULL,'ugn','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8044,6,NULL,'ugy','uruguayan sign language','1248825600',NULL,'ugy','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8045,6,NULL,'ukl','ukrainian sign language','1248825600',NULL,'ukl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8046,6,NULL,'uks','kaapor sign language','1248825600',NULL,'uks','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8046,6,NULL,'uks','urubú-kaapor sign language','1248825600',NULL,'uks','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8047,6,NULL,'urk','urak lawoi''','1248825600',NULL,'urk','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8048,6,NULL,'uzn','northern uzbek','1248825600',NULL,'uzn','uz',NULL,'uz',NULL,NULL); +INSERT INTO "iana_records" VALUES(8049,6,NULL,'uzs','southern uzbek','1248825600',NULL,'uzs','uz',NULL,'uz',NULL,NULL); +INSERT INTO "iana_records" VALUES(8050,6,NULL,'vgt','flemish sign language','1248825600',NULL,'vgt','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8050,6,NULL,'vgt','vlaamse gebarentaal','1248825600',NULL,'vgt','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8051,6,NULL,'vkk','kaur','1248825600',NULL,'vkk','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8052,6,NULL,'vkt','tenggarong kutai malay','1248825600',NULL,'vkt','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8053,6,NULL,'vsi','moldova sign language','1248825600',NULL,'vsi','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8054,6,NULL,'vsl','venezuelan sign language','1248825600',NULL,'vsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8055,6,NULL,'vsv','llengua de signes valenciana','1248825600',NULL,'vsv','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8055,6,NULL,'vsv','valencian sign language','1248825600',NULL,'vsv','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8056,6,NULL,'wuu','wu chinese','1248825600',NULL,'wuu','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(8057,6,NULL,'xki','kenyan sign language','1248825600',NULL,'xki','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8058,6,NULL,'xml','malaysian sign language','1248825600',NULL,'xml','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8059,6,NULL,'xmm','manado malay','1248825600',NULL,'xmm','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8060,6,NULL,'xms','moroccan sign language','1248825600',NULL,'xms','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8061,6,NULL,'yds','yiddish sign language','1248825600',NULL,'yds','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8062,6,NULL,'ysl','yugoslavian sign language','1248825600',NULL,'ysl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8063,6,NULL,'yue','yue chinese','1248825600',NULL,'yue','zh',NULL,'zh',NULL,NULL); +INSERT INTO "iana_records" VALUES(8064,6,NULL,'zib','zimbabwe sign language','1248825600',NULL,'zib','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8065,6,NULL,'zlm','malay (individual language)','1248825600',NULL,'zlm','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8066,6,NULL,'zmi','negeri sembilan malay','1248825600',NULL,'zmi','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8067,6,NULL,'zsl','zambian sign language','1248825600',NULL,'zsl','sgn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8068,1,NULL,'zsm','standard malay','1248825600',NULL,'zsm','ms',NULL,'ms',NULL,NULL); +INSERT INTO "iana_records" VALUES(8069,1,NULL,'arab','arabic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8070,1,NULL,'armi','imperial aramaic','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8071,1,NULL,'armn','armenian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8072,1,NULL,'avst','avestan','1185580800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8073,1,NULL,'bali','balinese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8074,1,NULL,'bamu','bamum','1248912000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8075,1,NULL,'bass','bassa vah','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8076,1,NULL,'batk','batak','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8077,1,NULL,'beng','bengali','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8078,1,NULL,'blis','blissymbols','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8079,1,NULL,'bopo','bopomofo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8080,1,NULL,'brah','brahmi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8081,1,NULL,'brai','braille','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8082,1,NULL,'bugi','buginese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8083,1,NULL,'buhd','buhid','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8084,1,NULL,'cakm','chakma','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8085,1,NULL,'cans','unified canadian aboriginal syllabics','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8086,1,NULL,'cari','carian','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8087,1,NULL,'cham','cham','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8088,1,NULL,'cher','cherokee','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8089,1,NULL,'cirt','cirth','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8090,1,NULL,'copt','coptic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8091,1,NULL,'cprt','cypriot','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8092,1,NULL,'cyrl','cyrillic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8093,1,NULL,'cyrs','cyrillic (old church slavonic variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8094,1,NULL,'deva','devanagari','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8094,1,NULL,'deva','nagari','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8095,1,NULL,'dsrt','deseret','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8095,1,NULL,'dsrt','mormon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8096,1,NULL,'egyd','egyptian demotic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8097,1,NULL,'egyh','egyptian hieratic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8098,1,NULL,'egyp','egyptian hieroglyphs','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8099,1,NULL,'ethi','ethiopic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8099,1,NULL,'ethi','ge''ez','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8099,1,NULL,'ethi','geʻez','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8100,1,NULL,'geok','khutsuri (asomtavruli and nuskhuri)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8101,1,NULL,'geor','georgian (mkhedruli)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8102,1,NULL,'glag','glagolitic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8103,1,NULL,'goth','gothic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8104,1,NULL,'gran','grantha','1260316800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8105,1,NULL,'grek','greek','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8106,1,NULL,'gujr','gujarati','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8107,1,NULL,'guru','gurmukhi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8108,1,NULL,'hang','hangeul','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8108,1,NULL,'hang','hangul','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8108,1,NULL,'hang','hangŭl','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8109,1,NULL,'hani','han','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8109,1,NULL,'hani','hanja','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8109,1,NULL,'hani','hanzi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8109,1,NULL,'hani','kanji','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8110,1,NULL,'hano','hanunoo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8110,1,NULL,'hano','hanunóo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8111,1,NULL,'hans','han (simplified variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8112,1,NULL,'hant','han (traditional variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8113,1,NULL,'hebr','hebrew','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8114,1,NULL,'hira','hiragana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8115,1,NULL,'hmng','pahawh hmong','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8116,1,NULL,'hrkt','(alias for hiragana + katakana)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8117,1,NULL,'hung','old hungarian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8118,1,NULL,'inds','harappan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8118,1,NULL,'inds','indus','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8119,1,NULL,'ital','old italic (etruscan, oscan, etc.)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8120,1,NULL,'java','javanese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8121,1,NULL,'jpan','japanese (alias for han + hiragana + katakana)','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8122,1,NULL,'kali','kayah li','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8123,1,NULL,'kana','katakana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8124,1,NULL,'khar','kharoshthi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8125,1,NULL,'khmr','khmer','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8126,1,NULL,'knda','kannada','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8127,1,NULL,'kore','korean (alias for hangul + han)','1183593600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8128,1,NULL,'kpel','kpelle','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8129,1,NULL,'kthi','kaithi','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8130,1,NULL,'lana','lanna','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8130,1,NULL,'lana','tai tham','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8131,1,NULL,'laoo','lao','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8132,1,NULL,'latf','latin (fraktur variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8133,1,NULL,'latg','latin (gaelic variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8134,1,NULL,'latn','latin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8135,1,NULL,'lepc','lepcha','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8135,1,NULL,'lepc','róng','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8136,1,NULL,'limb','limbu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8137,1,NULL,'lina','linear a','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8138,1,NULL,'linb','linear b','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8139,1,NULL,'lisu','fraser','1236902400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8139,1,NULL,'lisu','lisu','1236902400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8140,1,NULL,'loma','loma','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8141,1,NULL,'lyci','lycian','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8142,1,NULL,'lydi','lydian','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8143,1,NULL,'mand','mandaean','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8143,1,NULL,'mand','mandaic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8144,1,NULL,'mani','manichaean','1185580800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8145,1,NULL,'maya','mayan hieroglyphs','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8146,1,NULL,'mend','mende','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8147,1,NULL,'merc','meroitic cursive','1260316800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8148,1,NULL,'mero','meroitic hieroglyphs','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8149,1,NULL,'mlym','malayalam','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8150,1,NULL,'mong','mongolian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8151,1,NULL,'moon','moon','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8151,1,NULL,'moon','moon code','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8151,1,NULL,'moon','moon script','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8151,1,NULL,'moon','moon type','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8152,1,NULL,'mtei','meetei','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8152,1,NULL,'mtei','meitei mayek','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8152,1,NULL,'mtei','meithei','1169769600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8153,1,NULL,'mymr','burmese','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8153,1,NULL,'mymr','myanmar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8154,1,NULL,'narb','ancient north arabian','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8154,1,NULL,'narb','old north arabian','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8155,1,NULL,'nbat','nabataean','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8156,1,NULL,'nkgb','''na-''khi ²ggŏ-¹baw','1236902400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8156,1,NULL,'nkgb','nakhi geba','1236902400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8156,1,NULL,'nkgb','naxi geba','1236902400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8157,1,NULL,'nkoo','n''ko','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8157,1,NULL,'nkoo','n’ko','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8158,1,NULL,'ogam','ogham','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8159,1,NULL,'olck','ol','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8159,1,NULL,'olck','ol cemet''','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8159,1,NULL,'olck','ol chiki','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8159,1,NULL,'olck','santali','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8160,1,NULL,'orkh','old turkic','1248912000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8160,1,NULL,'orkh','orkhon runic','1248912000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8161,1,NULL,'orya','oriya','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8162,1,NULL,'osma','osmanya','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8163,1,NULL,'palm','palmyrene','1270857600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8164,1,NULL,'perm','old permic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8165,1,NULL,'phag','phags-pa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8166,1,NULL,'phli','inscriptional pahlavi','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8167,1,NULL,'phlp','psalter pahlavi','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8168,1,NULL,'phlv','book pahlavi','1185580800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8169,1,NULL,'phnx','phoenician','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8170,1,NULL,'plrd','miao','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8170,1,NULL,'plrd','pollard','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8171,1,NULL,'prti','inscriptional parthian','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8172,1,NULL,'qaaa..qabx','private use','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8173,1,NULL,'rjng','kaganga','1161043200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8173,1,NULL,'rjng','redjang','1161043200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8173,1,NULL,'rjng','rejang','1161043200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8174,1,NULL,'roro','rongorongo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8175,1,NULL,'runr','runic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8176,1,NULL,'samr','samaritan','1185580800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8177,1,NULL,'sara','sarati','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8178,1,NULL,'sarb','old south arabian','1248912000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8179,1,NULL,'saur','saurashtra','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8180,1,NULL,'sgnw','signwriting','1161043200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8181,1,NULL,'shaw','shavian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8181,1,NULL,'shaw','shaw','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8182,1,NULL,'sinh','sinhala','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8183,1,NULL,'sund','sundanese','1153440000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8184,1,NULL,'sylo','syloti nagri','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8185,1,NULL,'syrc','syriac','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8186,1,NULL,'syre','syriac (estrangelo variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8187,1,NULL,'syrj','syriac (western variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8188,1,NULL,'syrn','syriac (eastern variant)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8189,1,NULL,'tagb','tagbanwa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8190,1,NULL,'tale','tai le','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8191,1,NULL,'talu','new tai lue','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8192,1,NULL,'taml','tamil','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8193,1,NULL,'tavt','tai viet','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8194,1,NULL,'telu','telugu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8195,1,NULL,'teng','tengwar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8196,1,NULL,'tfng','berber','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8196,1,NULL,'tfng','tifinagh','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8197,1,NULL,'tglg','alibata','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8197,1,NULL,'tglg','baybayin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8197,1,NULL,'tglg','tagalog','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8198,1,NULL,'thaa','thaana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8199,1,NULL,'thai','thai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8200,1,NULL,'tibt','tibetan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8201,1,NULL,'ugar','ugaritic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8202,1,NULL,'vaii','vai','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8203,1,NULL,'visp','visible speech','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8204,1,NULL,'wara','varang kshiti','1260316800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8204,1,NULL,'wara','warang citi','1260316800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8205,1,NULL,'xpeo','old persian','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8206,1,NULL,'xsux','sumero-akkadian cuneiform','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8207,1,NULL,'yiii','yi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8208,1,NULL,'zinh','code for inherited script','1238716800',NULL,NULL,NULL,NULL,NULL,NULL,'not intended for use as a language subtag'); +INSERT INTO "iana_records" VALUES(8209,1,NULL,'zmth','mathematical notation','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8210,1,NULL,'zsym','symbols','1196812800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8211,1,NULL,'zxxx','code for unwritten documents','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8212,1,NULL,'zyyy','code for undetermined script','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8213,2,NULL,'zzzz','code for uncoded script','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8214,2,NULL,'aa','private use','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8215,2,NULL,'ac','ascension island','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8216,2,NULL,'ad','andorra','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8217,2,NULL,'ae','united arab emirates','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8218,2,NULL,'af','afghanistan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8219,2,NULL,'ag','antigua and barbuda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8220,2,NULL,'ai','anguilla','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8221,2,NULL,'al','albania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8222,2,NULL,'am','armenia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8223,2,NULL,'an','netherlands antilles','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8224,2,NULL,'ao','angola','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8225,2,NULL,'aq','antarctica','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8226,2,NULL,'ar','argentina','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8227,2,NULL,'as','american samoa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8228,2,NULL,'at','austria','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8229,2,NULL,'au','australia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8230,2,NULL,'aw','aruba','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8231,2,NULL,'ax','Åland islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8232,2,NULL,'az','azerbaijan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8233,2,NULL,'ba','bosnia and herzegovina','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8234,2,NULL,'bb','barbados','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8235,2,NULL,'bd','bangladesh','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8236,2,NULL,'be','belgium','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8237,2,NULL,'bf','burkina faso','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8238,2,NULL,'bg','bulgaria','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8239,2,NULL,'bh','bahrain','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8240,2,NULL,'bi','burundi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8241,2,NULL,'bj','benin','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8242,2,NULL,'bl','saint barthélemy','1193961600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8243,2,NULL,'bm','bermuda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8244,2,NULL,'bn','brunei darussalam','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8245,2,NULL,'bo','bolivia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8246,2,NULL,'br','brazil','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8247,2,NULL,'bs','bahamas','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8248,2,NULL,'bt','bhutan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8249,2,NULL,'bu','burma','1129420800',628819200,'mm',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8250,2,NULL,'bv','bouvet island','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8251,2,NULL,'bw','botswana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8252,2,NULL,'by','belarus','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8253,2,NULL,'bz','belize','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8254,2,NULL,'ca','canada','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8255,2,NULL,'cc','cocos (keeling) islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8256,2,NULL,'cd','the democratic republic of the congo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8257,2,NULL,'cf','central african republic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8258,2,NULL,'cg','congo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8259,2,NULL,'ch','switzerland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8260,2,NULL,'ci','côte d''ivoire','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8261,2,NULL,'ck','cook islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8262,2,NULL,'cl','chile','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8263,2,NULL,'cm','cameroon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8264,2,NULL,'cn','china','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8265,2,NULL,'co','colombia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8266,2,NULL,'cp','clipperton island','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8267,2,NULL,'cr','costa rica','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8268,2,NULL,'cs','serbia and montenegro','1129420800',1160006400,NULL,NULL,NULL,NULL,NULL,'see rs for serbia or me for montenegro'); +INSERT INTO "iana_records" VALUES(8269,2,NULL,'cu','cuba','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8270,2,NULL,'cv','cape verde','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8271,2,NULL,'cx','christmas island','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8272,2,NULL,'cy','cyprus','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8273,2,NULL,'cz','czech republic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8274,2,NULL,'dd','german democratic republic','1129420800',657244800,'de',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8275,2,NULL,'de','germany','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8276,2,NULL,'dg','diego garcia','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8277,2,NULL,'dj','djibouti','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8278,2,NULL,'dk','denmark','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8279,2,NULL,'dm','dominica','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8280,2,NULL,'do','dominican republic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8281,2,NULL,'dz','algeria','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8282,2,NULL,'ea','ceuta, melilla','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8283,2,NULL,'ec','ecuador','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8284,2,NULL,'ee','estonia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8285,2,NULL,'eg','egypt','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8286,2,NULL,'eh','western sahara','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8287,2,NULL,'er','eritrea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8288,2,NULL,'es','spain','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8289,2,NULL,'et','ethiopia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8290,2,NULL,'eu','european union','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8291,2,NULL,'fi','finland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8292,2,NULL,'fj','fiji','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8293,2,NULL,'fk','falkland islands (malvinas)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8294,2,NULL,'fm','federated states of micronesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8295,2,NULL,'fo','faroe islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8296,2,NULL,'fr','france','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8297,2,NULL,'fx','metropolitan france','1129420800',868838400,'fr',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8298,2,NULL,'ga','gabon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8299,2,NULL,'gb','united kingdom','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,'as of 2006-03-29 gb no longer includes the channel islands and isle of man; see gg, je, im'); +INSERT INTO "iana_records" VALUES(8300,2,NULL,'gd','grenada','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8301,2,NULL,'ge','georgia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8302,2,NULL,'gf','french guiana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8303,2,NULL,'gg','guernsey','1143590400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8304,2,NULL,'gh','ghana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8305,2,NULL,'gi','gibraltar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8306,2,NULL,'gl','greenland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8307,2,NULL,'gm','gambia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8308,2,NULL,'gn','guinea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8309,2,NULL,'gp','guadeloupe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8310,2,NULL,'gq','equatorial guinea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8311,2,NULL,'gr','greece','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8312,2,NULL,'gs','south georgia and the south sandwich islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8313,2,NULL,'gt','guatemala','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8314,2,NULL,'gu','guam','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8315,2,NULL,'gw','guinea-bissau','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8316,2,NULL,'gy','guyana','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8317,2,NULL,'hk','hong kong','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8318,2,NULL,'hm','heard island and mcdonald islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8319,2,NULL,'hn','honduras','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8320,2,NULL,'hr','croatia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8321,2,NULL,'ht','haiti','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8322,2,NULL,'hu','hungary','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8323,2,NULL,'ic','canary islands','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8324,2,NULL,'id','indonesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8325,2,NULL,'ie','ireland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8326,2,NULL,'il','israel','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8327,2,NULL,'im','isle of man','1143590400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8328,2,NULL,'in','india','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8329,2,NULL,'io','british indian ocean territory','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8330,2,NULL,'iq','iraq','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8331,2,NULL,'ir','islamic republic of iran','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8332,2,NULL,'is','iceland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8333,2,NULL,'it','italy','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8334,2,NULL,'je','jersey','1143590400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8335,2,NULL,'jm','jamaica','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8336,2,NULL,'jo','jordan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8337,2,NULL,'jp','japan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8338,2,NULL,'ke','kenya','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8339,2,NULL,'kg','kyrgyzstan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8340,2,NULL,'kh','cambodia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8341,2,NULL,'ki','kiribati','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8342,2,NULL,'km','comoros','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8343,2,NULL,'kn','saint kitts and nevis','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8344,2,NULL,'kp','democratic people''s republic of korea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8345,2,NULL,'kr','republic of korea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8346,2,NULL,'kw','kuwait','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8347,2,NULL,'ky','cayman islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8348,2,NULL,'kz','kazakhstan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8349,2,NULL,'la','lao people''s democratic republic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8350,2,NULL,'lb','lebanon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8351,2,NULL,'lc','saint lucia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8352,2,NULL,'li','liechtenstein','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8353,2,NULL,'lk','sri lanka','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8354,2,NULL,'lr','liberia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8355,2,NULL,'ls','lesotho','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8356,2,NULL,'lt','lithuania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8357,2,NULL,'lu','luxembourg','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8358,2,NULL,'lv','latvia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8359,2,NULL,'ly','libyan arab jamahiriya','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8360,2,NULL,'ma','morocco','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8361,2,NULL,'mc','monaco','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8362,2,NULL,'md','moldova','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8363,2,NULL,'me','montenegro','1160006400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8364,2,NULL,'mf','saint martin','1193961600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8365,2,NULL,'mg','madagascar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8366,2,NULL,'mh','marshall islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8367,2,NULL,'mk','the former yugoslav republic of macedonia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8368,2,NULL,'ml','mali','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8369,2,NULL,'mm','myanmar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8370,2,NULL,'mn','mongolia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8371,2,NULL,'mo','macao','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8372,2,NULL,'mp','northern mariana islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8373,2,NULL,'mq','martinique','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8374,2,NULL,'mr','mauritania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8375,2,NULL,'ms','montserrat','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8376,2,NULL,'mt','malta','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8377,2,NULL,'mu','mauritius','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8378,2,NULL,'mv','maldives','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8379,2,NULL,'mw','malawi','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8380,2,NULL,'mx','mexico','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8381,2,NULL,'my','malaysia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8382,2,NULL,'mz','mozambique','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8383,2,NULL,'na','namibia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8384,2,NULL,'nc','new caledonia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8385,2,NULL,'ne','niger','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8386,2,NULL,'nf','norfolk island','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8387,2,NULL,'ng','nigeria','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8388,2,NULL,'ni','nicaragua','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8389,2,NULL,'nl','netherlands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8390,2,NULL,'no','norway','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8391,2,NULL,'np','nepal','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8392,2,NULL,'nr','nauru','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8393,2,NULL,'nt','neutral zone','1129420800',742435200,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8394,2,NULL,'nu','niue','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8395,2,NULL,'nz','new zealand','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8396,2,NULL,'om','oman','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8397,2,NULL,'pa','panama','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8398,2,NULL,'pe','peru','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8399,2,NULL,'pf','french polynesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8400,2,NULL,'pg','papua new guinea','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8401,2,NULL,'ph','philippines','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8402,2,NULL,'pk','pakistan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8403,2,NULL,'pl','poland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8404,2,NULL,'pm','saint pierre and miquelon','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8405,2,NULL,'pn','pitcairn','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8406,2,NULL,'pr','puerto rico','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8407,2,NULL,'ps','occupied palestinian territory','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8408,2,NULL,'pt','portugal','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8409,2,NULL,'pw','palau','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8410,2,NULL,'py','paraguay','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8411,2,NULL,'qa','qatar','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8412,2,NULL,'qm..qz','private use','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8413,2,NULL,'re','réunion','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8414,2,NULL,'ro','romania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8415,2,NULL,'rs','serbia','1160006400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8416,2,NULL,'ru','russian federation','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8417,2,NULL,'rw','rwanda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8418,2,NULL,'sa','saudi arabia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8419,2,NULL,'sb','solomon islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8420,2,NULL,'sc','seychelles','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8421,2,NULL,'sd','sudan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8422,2,NULL,'se','sweden','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8423,2,NULL,'sg','singapore','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8424,2,NULL,'sh','saint helena, ascension and tristan da cunha','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8425,2,NULL,'si','slovenia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8426,2,NULL,'sj','svalbard and jan mayen','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8427,2,NULL,'sk','slovakia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8428,2,NULL,'sl','sierra leone','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8429,2,NULL,'sm','san marino','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8430,2,NULL,'sn','senegal','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8431,2,NULL,'so','somalia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8432,2,NULL,'sr','suriname','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8433,2,NULL,'st','sao tome and principe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8434,2,NULL,'su','union of soviet socialist republics','1129420800',715132800,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8435,2,NULL,'sv','el salvador','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8436,2,NULL,'sy','syrian arab republic','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8437,2,NULL,'sz','swaziland','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8438,2,NULL,'ta','tristan da cunha','1248825600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8439,2,NULL,'tc','turks and caicos islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8440,2,NULL,'td','chad','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8441,2,NULL,'tf','french southern territories','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8442,2,NULL,'tg','togo','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8443,2,NULL,'th','thailand','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8444,2,NULL,'tj','tajikistan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8445,2,NULL,'tk','tokelau','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8446,2,NULL,'tl','timor-leste','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8447,2,NULL,'tm','turkmenistan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8448,2,NULL,'tn','tunisia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8449,2,NULL,'to','tonga','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8450,2,NULL,'tp','east timor','1129420800',1021852800,'tl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8451,2,NULL,'tr','turkey','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8452,2,NULL,'tt','trinidad and tobago','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8453,2,NULL,'tv','tuvalu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8454,2,NULL,'tw','taiwan, province of china','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8455,2,NULL,'tz','united republic of tanzania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8456,2,NULL,'ua','ukraine','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8457,2,NULL,'ug','uganda','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8458,2,NULL,'um','united states minor outlying islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8459,2,NULL,'us','united states','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8460,2,NULL,'uy','uruguay','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8461,2,NULL,'uz','uzbekistan','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8462,2,NULL,'va','holy see (vatican city state)','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8463,2,NULL,'vc','saint vincent and the grenadines','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8464,2,NULL,'ve','venezuela','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8465,2,NULL,'vg','british virgin islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8466,2,NULL,'vi','u.s. virgin islands','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8467,2,NULL,'vn','viet nam','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8468,2,NULL,'vu','vanuatu','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8469,2,NULL,'wf','wallis and futuna','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8470,2,NULL,'ws','samoa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8471,2,NULL,'xa..xz','private use','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8472,2,NULL,'yd','democratic yemen','1129420800',650592000,'ye',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8473,2,NULL,'ye','yemen','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8474,2,NULL,'yt','mayotte','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8475,2,NULL,'yu','yugoslavia','1129420800',1058918400,NULL,NULL,NULL,NULL,NULL,'see ba, hr, me, mk, rs, or si'); +INSERT INTO "iana_records" VALUES(8476,2,NULL,'za','south africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8477,2,NULL,'zm','zambia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8478,2,NULL,'zr','zaire','1129420800',868838400,'cd',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8479,2,NULL,'zw','zimbabwe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8480,2,NULL,'zz','private use','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8481,2,NULL,'001','world','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8482,2,NULL,'002','africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8483,2,NULL,'005','south america','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8484,2,NULL,'009','oceania','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8485,2,NULL,'011','western africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8486,2,NULL,'013','central america','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8487,2,NULL,'014','eastern africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8488,2,NULL,'015','northern africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8489,2,NULL,'017','middle africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8490,2,NULL,'018','southern africa','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8491,2,NULL,'019','americas','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8492,2,NULL,'021','northern america','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8493,2,NULL,'029','caribbean','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8494,2,NULL,'030','eastern asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8495,2,NULL,'034','southern asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8496,2,NULL,'035','south-eastern asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8497,2,NULL,'039','southern europe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8498,2,NULL,'053','australia and new zealand','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8499,2,NULL,'054','melanesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8500,2,NULL,'057','micronesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8501,2,NULL,'061','polynesia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8502,2,NULL,'142','asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8503,2,NULL,'143','central asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8504,2,NULL,'145','western asia','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8505,2,NULL,'150','europe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8506,2,NULL,'151','eastern europe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8507,2,NULL,'154','northern europe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8508,2,NULL,'155','western europe','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8509,3,NULL,'419','latin america and the caribbean','1129420800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8510,3,NULL,'1606nict','late middle french (to 1606)','1174348800',NULL,NULL,'frm',NULL,NULL,NULL,'16th century french as in jean nicot, "thresor de la langue francoyse", 1606, but also including some french similar to that of rabelais'); +INSERT INTO "iana_records" VALUES(8511,3,NULL,'1694acad','early modern french','1174348800',NULL,NULL,'fr',NULL,NULL,NULL,'17th century french, as catalogued in the "dictionnaire de l''académie françoise", 4eme ed. 1694; frequently includes elements of middle french, as this is a transitional period'); +INSERT INTO "iana_records" VALUES(8512,3,NULL,'1901','traditional german orthography','1129420800',NULL,NULL,'de',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8513,3,NULL,'1959acad','"academic" ("governmental") variant of belarusian as codified in 1959','1222732800',NULL,NULL,'be',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8514,3,NULL,'1994','standardized resian orthography','1185580800',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'for standardized resian an orthography was published in 1994.'); +INSERT INTO "iana_records" VALUES(8514,3,NULL,'1994','standardized resian orthography','1185580800',NULL,NULL,'sl-rozaj-biske',NULL,NULL,NULL,'for standardized resian an orthography was published in 1994.'); +INSERT INTO "iana_records" VALUES(8514,3,NULL,'1994','standardized resian orthography','1185580800',NULL,NULL,'sl-rozaj-njiva',NULL,NULL,NULL,'for standardized resian an orthography was published in 1994.'); +INSERT INTO "iana_records" VALUES(8514,3,NULL,'1994','standardized resian orthography','1185580800',NULL,NULL,'sl-rozaj-osojs',NULL,NULL,NULL,'for standardized resian an orthography was published in 1994.'); +INSERT INTO "iana_records" VALUES(8514,3,NULL,'1994','standardized resian orthography','1185580800',NULL,NULL,'sl-rozaj-solba',NULL,NULL,NULL,'for standardized resian an orthography was published in 1994.'); +INSERT INTO "iana_records" VALUES(8515,3,NULL,'1996','german orthography of 1996','1129420800',NULL,NULL,'de',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8516,3,NULL,'alalc97','ala-lc romanization, 1997 edition','1260316800',NULL,NULL,NULL,NULL,NULL,NULL,'romanizations recommended by the american library association and the library of congress, in "ala-lc romanization tables: transliteration schemes for non-roman scripts" (1997), isbn 978-0-8444-0940-5.'); +INSERT INTO "iana_records" VALUES(8517,3,NULL,'aluku','aluku dialect','1252108800',NULL,NULL,'djk',NULL,NULL,NULL,'aluku dialect of the "busi nenge tongo" english-based creole continuum in eastern suriname and western french guiana'); +INSERT INTO "iana_records" VALUES(8517,3,NULL,'aluku','boni dialect','1252108800',NULL,NULL,'djk',NULL,NULL,NULL,'aluku dialect of the "busi nenge tongo" english-based creole continuum in eastern suriname and western french guiana'); +INSERT INTO "iana_records" VALUES(8518,3,NULL,'arevela','eastern armenian','1158537600',NULL,NULL,'hy',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8519,3,NULL,'arevmda','western armenian','1158537600',NULL,NULL,'hy',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'az',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'ba',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'crh',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'kk',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'krc',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'ky',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'sah',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'tk',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'tt',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8520,3,NULL,'baku1926','unified turkic latin alphabet (historical)','1176854400',NULL,NULL,'uz',NULL,NULL,NULL,'denotes alphabet used in turkic republics/regions of the former ussr in late 1920s, and throughout 1930s, which aspired to represent equivalent phonemes in a unified fashion. also known as: new turkic alphabet; birlәşdirilmiş jeni tyrk Әlifbasь (birlesdirilmis jeni tyrk elifbasi); jaŋalif (janalif).'); +INSERT INTO "iana_records" VALUES(8521,3,NULL,'biscayan','biscayan dialect of basque','1271116800',NULL,NULL,'eu',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8522,3,NULL,'biske','the bila dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of san giorgio/bila is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8522,3,NULL,'biske','the san giorgio dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of san giorgio/bila is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8523,3,NULL,'boont','boontling','1158537600',NULL,NULL,'en',NULL,NULL,NULL,'jargon embedded in american english'); +INSERT INTO "iana_records" VALUES(8524,3,NULL,'fonipa','international phonetic alphabet','1165795200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8525,3,NULL,'fonupa','uralic phonetic alphabet','1165795200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8526,3,NULL,'hepburn','hepburn romanization','1254355200',NULL,NULL,'ja-latn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8527,3,NULL,'heploc','hepburn romanization, library of congress method','1254355200',1265500800,'alalc97','ja-latn-hepburn',NULL,NULL,NULL,'preferred tag is ja-latn-alalc97'); +INSERT INTO "iana_records" VALUES(8528,3,NULL,'hognorsk','norwegian in høgnorsk (high norwegian) orthography','1262390400',NULL,NULL,'nn',NULL,NULL,NULL,'norwegian following ivar aasen''s orthographical principles, including modern usage.'); +INSERT INTO "iana_records" VALUES(8529,3,NULL,'jauer','jauer dialect of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'the spoken dialect of the val müstair, which has no written standard.'); +INSERT INTO "iana_records" VALUES(8530,3,NULL,'kkcor','common cornish orthography of revived cornish','1223942400',NULL,NULL,'kw',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8531,3,NULL,'lipaw','the lipovaz dialect of resian','1186790400',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of lipovaz/lipovec is one of the minor local dialects of resian'); +INSERT INTO "iana_records" VALUES(8531,3,NULL,'lipaw','the lipovec dialect of resian','1186790400',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of lipovaz/lipovec is one of the minor local dialects of resian'); +INSERT INTO "iana_records" VALUES(8532,3,NULL,'monoton','monotonic greek','1165795200',NULL,NULL,'el',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8533,3,NULL,'ndyuka','aukan dialect','1252108800',NULL,NULL,'djk',NULL,NULL,NULL,'ndyuka dialect of the "busi nenge tongo" english-based creole continuum in eastern suriname and western french guiana'); +INSERT INTO "iana_records" VALUES(8533,3,NULL,'ndyuka','ndyuka dialect','1252108800',NULL,NULL,'djk',NULL,NULL,NULL,'ndyuka dialect of the "busi nenge tongo" english-based creole continuum in eastern suriname and western french guiana'); +INSERT INTO "iana_records" VALUES(8534,3,NULL,'nedis','nadiza dialect','1129420800',NULL,NULL,'sl',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8534,3,NULL,'nedis','natisone dialect','1129420800',NULL,NULL,'sl',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8535,3,NULL,'njiva','the gniva dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of gniva/njiva is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8535,3,NULL,'njiva','the njiva dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of gniva/njiva is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8536,3,NULL,'osojs','the oseacco dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of oseacco/osojane is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8536,3,NULL,'osojs','the osojane dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of oseacco/osojane is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8537,3,NULL,'pamaka','pamaka dialect','1252108800',NULL,NULL,'djk',NULL,NULL,NULL,'pamaka dialect of the "busi nenge tongo" english-based creole continuum in eastern suriname and western french guiana'); +INSERT INTO "iana_records" VALUES(8538,3,NULL,'pinyin','pinyin romanization','1223942400',NULL,NULL,'bo-latn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8538,3,NULL,'pinyin','pinyin romanization','1223942400',NULL,NULL,'zh-latn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8539,3,NULL,'polyton','polytonic greek','1165795200',NULL,NULL,'el',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8540,3,NULL,'puter','puter idiom of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'puter is one of the five traditional written standards or "idioms" of the romansh language.'); +INSERT INTO "iana_records" VALUES(8541,3,NULL,'rozaj','resian','1129420800',NULL,NULL,'sl',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8541,3,NULL,'rozaj','resianic','1129420800',NULL,NULL,'sl',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8541,3,NULL,'rozaj','rezijan','1129420800',NULL,NULL,'sl',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8542,3,NULL,'rumgr','rumantsch grischun','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'supraregional romansh written standard'); +INSERT INTO "iana_records" VALUES(8543,3,NULL,'scotland','scottish standard english','1188518400',NULL,NULL,'en',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8544,3,NULL,'scouse','scouse','1158537600',NULL,NULL,'en',NULL,NULL,NULL,'english liverpudlian dialect known as ''scouse'''); +INSERT INTO "iana_records" VALUES(8545,3,NULL,'solba','the solbica dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of stolvizza/solbica is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8545,3,NULL,'solba','the stolvizza dialect of resian','1183593600',NULL,NULL,'sl-rozaj',NULL,NULL,NULL,'the dialect of stolvizza/solbica is one of the four major local dialects of resian'); +INSERT INTO "iana_records" VALUES(8546,3,NULL,'surmiran','surmiran idiom of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'surmiran is one of the five traditional written standards or "idioms" of the romansh language.'); +INSERT INTO "iana_records" VALUES(8547,3,NULL,'sursilv','sursilvan idiom of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'sursilvan is one of the five traditional written standards or "idioms" of the romansh language.'); +INSERT INTO "iana_records" VALUES(8548,3,NULL,'sutsilv','sutsilvan idiom of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'sutsilvan is one of the five traditional written standards or "idioms" of the romansh language.'); +INSERT INTO "iana_records" VALUES(8549,3,NULL,'tarask','belarusian in taraskievica orthography','1177632000',NULL,NULL,'be',NULL,NULL,NULL,'the subtag represents branislau taraskievic''s belarusian orthography as published in "bielaruski klasycny pravapis" by juras buslakou, vincuk viacorka, zmicier sanko, and zmicier sauka (vilnia- miensk 2005).'); +INSERT INTO "iana_records" VALUES(8550,3,NULL,'uccor','unified cornish orthography of revived cornish','1223942400',NULL,NULL,'kw',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8551,3,NULL,'ucrcor','unified cornish revised orthography of revived cornish','1223942400',NULL,NULL,'kw',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8552,3,NULL,'ulster','ulster dialect of scots','1270857600',NULL,NULL,'sco',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8553,3,NULL,'valencia','valencian','1173139200',NULL,NULL,'ca',NULL,NULL,NULL,'variety spoken in the "comunidad valenciana" region of spain, where it is co-official with spanish.'); +INSERT INTO "iana_records" VALUES(8554,3,NULL,'vallader','vallader idiom of romansh','1277769600',NULL,NULL,'rm',NULL,NULL,NULL,'vallader is one of the five traditional written standards or "idioms" of the romansh language.'); +INSERT INTO "iana_records" VALUES(8555,4,NULL,'wadegile','wade-giles romanization','1222992000',NULL,NULL,'zh-latn',NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8556,4,'art-lojban',NULL,'lojban','1005436800',1062460800,'jbo',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8557,4,'cel-gaulish',NULL,'gaulish','990748800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8558,4,'en-gb-oed',NULL,'english, oxford english dictionary spelling','1057708800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8559,4,'i-ami',NULL,'amis','927590400',1248825600,'ami',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8560,4,'i-bnn',NULL,'bunun','927590400',1248825600,'bnn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8561,4,'i-default',NULL,'default language','889488000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8562,4,'i-enochian',NULL,'enochian','1025654400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8563,4,'i-hak',NULL,'hakka','917740800',947462400,'hak',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8564,4,'i-klingon',NULL,'klingon','927676800',1077580800,'tlh',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8565,4,'i-lux',NULL,'luxembourgish','874627200',905299200,'lb',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8566,4,'i-mingo',NULL,'mingo','874627200',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8567,4,'i-navajo',NULL,'navajo','874627200',950832000,'nv',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8568,4,'i-pwn',NULL,'paiwan','927590400',1248825600,'pwn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8569,4,'i-tao',NULL,'tao','927590400',1248825600,'tao',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8570,4,'i-tay',NULL,'tayal','927590400',1248825600,'tay',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8571,4,'i-tsu',NULL,'tsou','927590400',1248825600,'tsu',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8572,4,'no-bok',NULL,'norwegian bokmal','809136000',950832000,'nb',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8573,4,'no-nyn',NULL,'norwegian nynorsk','809136000',950832000,'nn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8574,4,'sgn-be-fr',NULL,'belgian-french sign language','1005436800',1248825600,'sfb',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8575,4,'sgn-be-nl',NULL,'belgian-flemish sign language','1005436800',1248825600,'vgt',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8576,4,'sgn-ch-de',NULL,'swiss german sign language','1005436800',1248825600,'sgg',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8577,4,'zh-guoyu',NULL,'mandarin or standard chinese','945475200',1121385600,'cmn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8578,4,'zh-hakka',NULL,'hakka','945475200',1248825600,'hak',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8579,4,'zh-min',NULL,'min, fuzhou, hokkien, amoy, or taiwanese','945475200',1248825600,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8580,4,'zh-min-nan',NULL,'minnan, hokkien, amoy, taiwanese, southern min, southern fujian, hoklo, southern fukien, ho-lo','985564800',1248825600,'nan',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8581,5,'zh-xiang',NULL,'xiang or hunanese','945475200',1248825600,'hsn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8582,5,'az-arab',NULL,'azerbaijani in arabic script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8583,5,'az-cyrl',NULL,'azerbaijani in cyrillic script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8584,5,'az-latn',NULL,'azerbaijani in latin script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8585,5,'be-latn',NULL,'belarusian in latin script','1104969600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8586,5,'bs-cyrl',NULL,'bosnian in cyrillic script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8587,5,'bs-latn',NULL,'bosnian in latin script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8588,5,'de-1901',NULL,'german, traditional orthography','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8589,5,'de-1996',NULL,'german, orthography of 1996','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8590,5,'de-at-1901',NULL,'german, austrian variant, traditional orthography','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8591,5,'de-at-1996',NULL,'german, austrian variant, orthography of 1996','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8592,5,'de-ch-1901',NULL,'german, swiss variant, traditional orthography','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8593,5,'de-ch-1996',NULL,'german, swiss variant, orthography of 1996','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8594,5,'de-de-1901',NULL,'german, german variant, traditional orthography','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8595,5,'de-de-1996',NULL,'german, german variant, orthography of 1996','995328000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8596,5,'en-boont',NULL,'boontling','1045180800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8597,5,'en-scouse',NULL,'scouse','959212800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8598,5,'es-419',NULL,'latin american spanish','1121385600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8599,5,'iu-cans',NULL,'inuktitut in canadian aboriginal syllabic script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8600,5,'iu-latn',NULL,'inuktitut in latin script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8601,5,'mn-cyrl',NULL,'mongolian in cyrillic script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8602,5,'mn-mong',NULL,'mongolian in mongolian script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8603,5,'sgn-br',NULL,'brazilian sign language','1005436800',1248825600,'bzs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8604,5,'sgn-co',NULL,'colombian sign language','1005436800',1248825600,'csn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8605,5,'sgn-de',NULL,'german sign language','1005436800',1248825600,'gsg',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8606,5,'sgn-dk',NULL,'danish sign language','1005436800',1248825600,'dsl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8607,5,'sgn-es',NULL,'spanish sign language','1005436800',1248825600,'ssp',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8608,5,'sgn-fr',NULL,'french sign language','1005436800',1248825600,'fsl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8609,5,'sgn-gb',NULL,'british sign language','983491200',1248825600,'bfi',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8610,5,'sgn-gr',NULL,'greek sign language','1005436800',1248825600,'gss',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8611,5,'sgn-ie',NULL,'irish sign language','983491200',1248825600,'isg',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8612,5,'sgn-it',NULL,'italian sign language','1005436800',1248825600,'ise',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8613,5,'sgn-jp',NULL,'japanese sign language','1005436800',1248825600,'jsl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8614,5,'sgn-mx',NULL,'mexican sign language','1005436800',1248825600,'mfs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8615,5,'sgn-ni',NULL,'nicaraguan sign language','983491200',1248825600,'ncs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8616,5,'sgn-nl',NULL,'dutch sign language','1005436800',1248825600,'dse',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8617,5,'sgn-no',NULL,'norwegian sign language','1005436800',1248825600,'nsl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8618,5,'sgn-pt',NULL,'portuguese sign language','1005436800',1248825600,'psr',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8619,5,'sgn-se',NULL,'swedish sign language','1005436800',1248825600,'swl',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8620,5,'sgn-us',NULL,'american sign language','983491200',1248825600,'ase',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8621,5,'sgn-za',NULL,'south african sign language','1005436800',1248825600,'sfs',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8622,5,'sl-nedis',NULL,'natisone dialect, nadiza dialect','1086048000',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8623,5,'sl-rozaj',NULL,'resian, resianic, rezijan','1065657600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8624,5,'sr-cyrl',NULL,'serbian in cyrillic script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8625,5,'sr-latn',NULL,'serbian in latin script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8626,5,'tg-arab',NULL,'tajik in arabic script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8627,5,'tg-cyrl',NULL,'tajik in cyrillic script','1108598400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8628,5,'uz-cyrl',NULL,'uzbek in cyrillic script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8629,5,'uz-latn',NULL,'uzbek in latin script','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8630,5,'yi-latn',NULL,'yiddish, in latin script','1041897600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8631,5,'zh-cmn',NULL,'mandarin chinese','1121385600',1248825600,'cmn',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8632,5,'zh-cmn-hans',NULL,'mandarin chinese (simplified)','1121385600',1248825600,'cmn-hans',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8633,5,'zh-cmn-hant',NULL,'mandarin chinese (traditional)','1121385600',1248825600,'cmn-hant',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8634,5,'zh-gan',NULL,'kan or gan','945475200',1248825600,'gan',NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8635,5,'zh-hans',NULL,'simplified chinese','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8636,5,'zh-hans-cn',NULL,'prc mainland chinese in simplified script','1113350400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8637,5,'zh-hans-hk',NULL,'hong kong chinese in simplified script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8638,5,'zh-hans-mo',NULL,'macao chinese in simplified script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8639,5,'zh-hans-sg',NULL,'singapore chinese in simplified script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8640,5,'zh-hans-tw',NULL,'taiwan chinese in simplified script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8641,5,'zh-hant',NULL,'traditional chinese','1054252800',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8642,5,'zh-hant-cn',NULL,'prc mainland chinese in traditional script','1113350400',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8643,5,'zh-hant-hk',NULL,'hong kong chinese in traditional script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8644,5,'zh-hant-mo',NULL,'macao chinese in traditional script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8645,5,'zh-hant-sg',NULL,'singapore chinese in traditional script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8646,5,'zh-hant-tw',NULL,'taiwan chinese in traditional script','1113177600',NULL,NULL,NULL,NULL,NULL,NULL,NULL); +INSERT INTO "iana_records" VALUES(8647,5,'zh-wuu',NULL,'shanghaiese or wu','945475200',1248825600,'wuu',NULL,NULL,NULL,NULL,NULL); +COMMIT; ) diff --git a/modules/i18n/dao/orm/orm_generator_i18n.h b/modules/i18n/dao/orm/orm_generator_i18n.h new file mode 100644 index 0000000..53cfea3 --- /dev/null +++ b/modules/i18n/dao/orm/orm_generator_i18n.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ORM_GENERATOR_I18N_H_ +#define _ORM_GENERATOR_I18N_H_ + +#define ORM_GENERATOR_DATABASE_NAME i18n_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif // _ORM_GENERATOR_I18N_H_ diff --git a/modules/i18n/dao/orm/version_db b/modules/i18n/dao/orm/version_db new file mode 100644 index 0000000..7e20d8d --- /dev/null +++ b/modules/i18n/dao/orm/version_db @@ -0,0 +1,5 @@ +SQL( + BEGIN TRANSACTION; + CREATE TABLE DB_CHECKSUM (version INT); + COMMIT; +) diff --git a/modules/i18n/dao/src/i18n_dao_read_only.cpp b/modules/i18n/dao/src/i18n_dao_read_only.cpp new file mode 100644 index 0000000..19822ff --- /dev/null +++ b/modules/i18n/dao/src/i18n_dao_read_only.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the definition of i18n dao namespace. + * + * @file i18n_dao_read_only.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file contains the definition of i18n dao + */ + +#include +#include + +#include + +using namespace DPL::DB::ORM; +using namespace DPL::DB::ORM::i18n; + +namespace I18n { +namespace DB { +namespace I18nDAOReadOnly { +bool IsValidSubTag(const DPL::String& tag, int type) +{ + I18N_DB_SELECT(select, iana_records) + select->Where(And(Equals(tag), + Equals(type))); + return !select->GetRowList().empty(); +} +} +} +} diff --git a/modules/i18n/dao/src/i18n_database.cpp b/modules/i18n/dao/src/i18n_database.cpp new file mode 100644 index 0000000..e1a1fc5 --- /dev/null +++ b/modules/i18n/dao/src/i18n_database.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +namespace I18n { +namespace DB { +namespace Interface { +namespace { +const char* const I18N_DB_FILE_PATH = "/opt/usr/dbspace/.wrt_i18n.db"; + +DPL::DB::SqlConnection::Flag::Type I18N_DB_FLAGS = + DPL::DB::SqlConnection::Flag::UseLucene; +} + +DPL::Mutex g_dbQueriesMutex; +DPL::DB::ThreadDatabaseSupport g_dbInterface(I18N_DB_FILE_PATH, + I18N_DB_FLAGS); + +void attachDatabaseRO() +{ + g_dbInterface.AttachToThread(DPL::DB::SqlConnection::Flag::RO); +} + +void detachDatabase() +{ + g_dbInterface.DetachFromThread(); +} +} //namespace Interface +} //namespace DB +} //namespace I18n diff --git a/modules/localization/config.cmake b/modules/localization/config.cmake new file mode 100644 index 0000000..80f77c4 --- /dev/null +++ b/modules/localization/config.cmake @@ -0,0 +1,39 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Soyoung Kim(sy037.kim@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_LOCALIZATION_SOURCES + ${PROJECT_SOURCE_DIR}/modules/localization/src/w3c_file_localization.cpp + ${PROJECT_SOURCE_DIR}/modules/localization/src/LanguageTagsProvider.cpp + PARENT_SCOPE +) + + +SET(DPL_LOCALIZATION_HEADERS + ${PROJECT_SOURCE_DIR}/modules/localization/include/dpl/localization/localization_utils.h + ${PROJECT_SOURCE_DIR}/modules/localization/include/dpl/localization/w3c_file_localization.h + ${PROJECT_SOURCE_DIR}/modules/localization/include/LanguageTagsProvider.h + PARENT_SCOPE +) + +SET(DPL_LOCALIZATION_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/localization/include + PARENT_SCOPE +) diff --git a/modules/localization/include/LanguageTagsProvider.h b/modules/localization/include/LanguageTagsProvider.h new file mode 100644 index 0000000..529101f --- /dev/null +++ b/modules/localization/include/LanguageTagsProvider.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file LanguageTagsProvider.h + * @author Marcin Kaminski (marcin.ka@samsung.com) + * @version 1.0 + */ + +#ifndef LANGUAGETAGSPROVIDER_H +#define LANGUAGETAGSPROVIDER_H + +#include +#include +#include +#include + +typedef std::list LanguageTags; + +class LanguageTagsProvider +{ + public: + /* + * Get list of currently set language tags + */ + const LanguageTags getLanguageTags() const; + + /* + * Set new language tags (other than based on system locales) + */ + void setLanguageTags(const LanguageTags& taglist); + + /* + * Set language tags from given locales. + * Supported format is: xx[-yy[-zz]][.encoding] + */ + void setLanguageTagsFromLocales(const char* locales); + + /* + * Set language tags based on system language settings + */ + void resetLanguageTags(); + + /* + * Adds default widget locales to language tags if + * it doesn't exist within actual tags. + * Default locales i added: + * - at the beginning if less then 2 tags exists on list + * - just before empty ("") locales - pre-last position + * - at the end if last position is not empty locale + */ + void addWidgetDefaultLocales(const DPL::String&); + + /* + * Function converts language tag string (i.e. en-US) + * into locales string (en_US). + */ + static DPL::String BCP47LanguageTagToLocale(const DPL::String&); + + /* + * Function converts locales string (i.e. en_US.UTF-8) into language tag + * (i.e. en-US) + */ + static DPL::String LocaleToBCP47LanguageTag(const DPL::String&); + + private: + friend class DPL::Singleton; + + LanguageTags m_languageTagsList; + + LanguageTagsProvider(); + virtual ~LanguageTagsProvider(); + + void loadSystemTags(); + void createTagsFromLocales(const char* language); +}; + +typedef DPL::Singleton LanguageTagsProviderSingleton; + +#endif /* LANGUAGETAGSPROVIDER_H */ diff --git a/modules/localization/include/dpl/localization/localization_utils.h b/modules/localization/include/dpl/localization/localization_utils.h new file mode 100644 index 0000000..66a232d --- /dev/null +++ b/modules/localization/include/dpl/localization/localization_utils.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file localization_utils.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + */ + +#ifndef LOCALIZATION_UTILS_H +#define LOCALIZATION_UTILS_H + +#include + +#include +#include +#include +#include + +/** + * WidgetIcon + * Structure to hold information about widget icon. + */ + +struct WidgetIcon +{ + WidgetIcon() : + width(DPL::Optional::Null), + height(DPL::Optional::Null) + {} + + /* + * a valid URI to an image file inside the widget package that represents an + * iconic representation of the widget + */ + DPL::String src; + DPL::Optional width; /// the width of the icon in pixels + DPL::Optional height; /// the height of the icon in pixels + + bool operator==(const WidgetIcon &other) const + { + return src == other.src; + } +}; + +struct WidgetStartFileInfo +{ + DPL::String file; + DPL::String localizedPath; + DPL::String encoding; + DPL::String type; + + bool operator==(const WidgetStartFileInfo& other) const + { + return file == other.file && + localizedPath == other.localizedPath && + encoding == other.encoding && + type == other.type; + } +}; + +typedef DPL::Optional OptionalWidgetIcon; +typedef DPL::Optional OptionalWidgetStartFileInfo; + +#endif //LOCALIZATION_UTILS_H diff --git a/modules/localization/include/dpl/localization/w3c_file_localization.h b/modules/localization/include/dpl/localization/w3c_file_localization.h new file mode 100755 index 0000000..7a437d8 --- /dev/null +++ b/modules/localization/include/dpl/localization/w3c_file_localization.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file w3c_file_localization.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + */ + +#ifndef W3C_FILE_LOCALIZATION_H +#define W3C_FILE_LOCALIZATION_H + +#include +#include +#include +#include + +#include + +// WrtDB::DbWidgetHandle +#include + +namespace W3CFileLocalization { +typedef std::list WidgetIconList; + +DPL::Optional getFilePathInWidgetPackageFromUrl( + const WrtDB::TizenAppId &tzAppId, + const DPL::String &url); +DPL::Optional getFilePathInWidgetPackageFromUrl( + WrtDB::WidgetDAOReadOnlyPtr dao, + const DPL::String &url); +std::string getFilePathInWidgetPackageFromUrl(const std::string &tzAppId, const std::string &url); + +DPL::Optional getFilePathInWidgetPackage( + const WrtDB::TizenAppId &tzAppId, + const DPL::String& file); +DPL::Optional getFilePathInWidgetPackage( + WrtDB::WidgetDAOReadOnlyPtr dao, + const DPL::String& file); + +DPL::OptionalString getStartFile(const WrtDB::TizenAppId & tzAppId); +DPL::OptionalString getStartFile(WrtDB::WidgetDAOReadOnlyPtr dao); + +OptionalWidgetIcon getIcon(const WrtDB::TizenAppId & tzAppId); +OptionalWidgetIcon getIcon(WrtDB::WidgetDAOReadOnlyPtr dao); + +WidgetIconList getValidIconsList( + const WrtDB::TizenAppId &tzAppId); +WidgetIconList getValidIconsList( + WrtDB::WidgetDAOReadOnlyPtr dao); + +OptionalWidgetStartFileInfo getStartFileInfo( + const WrtDB::TizenAppId &tzAppId); +OptionalWidgetStartFileInfo getStartFileInfo( + WrtDB::WidgetDAOReadOnlyPtr dao); + +WrtDB::WidgetLocalizedInfo getLocalizedInfo( + const WrtDB::TizenAppId & tzAppId); +WrtDB::WidgetLocalizedInfo getLocalizedInfo(WrtDB::WidgetDAOReadOnlyPtr dao); +} + +#endif //W3C_FILE_LOCALIZATION_H diff --git a/modules/localization/src/LanguageTagsProvider.cpp b/modules/localization/src/LanguageTagsProvider.cpp new file mode 100644 index 0000000..848cc34 --- /dev/null +++ b/modules/localization/src/LanguageTagsProvider.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file LanguageTagsProvider.cpp + * @author Marcin Kaminski (marcin.ka@samsung.com) + * @version 1.0 + */ + +#include "LanguageTagsProvider.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +IMPLEMENT_SINGLETON(LanguageTagsProvider) + +/* ========== public ========== */ +const LanguageTags LanguageTagsProvider::getLanguageTags() const +{ + return m_languageTagsList; +} + +void LanguageTagsProvider::setLanguageTags(const LanguageTags& taglist) +{ + m_languageTagsList = taglist; + /* If given list does not contain default value (empty string) + * than append it to the list. + * In case of empty list given as parameter only default value + * will exist on m_languageTagsList. */ + DPL::String tofind = L""; + if (std::find(m_languageTagsList.begin(), m_languageTagsList.end(), + tofind) == m_languageTagsList.end()) + { + m_languageTagsList.push_back(L""); + } +} + +void LanguageTagsProvider::setLanguageTagsFromLocales(const char* locales) +{ + LogDebug("Setting new language tags for locales " << locales); + this->createTagsFromLocales(locales); +} + +void LanguageTagsProvider::resetLanguageTags() +{ + this->loadSystemTags(); +} + +void LanguageTagsProvider::addWidgetDefaultLocales( + const DPL::String& defaultLocale) +{ + if (defaultLocale.size() > 0 && + std::find(m_languageTagsList.begin(), m_languageTagsList.end(), + defaultLocale) == m_languageTagsList.end()) + { + if (m_languageTagsList.size() < 2) { + m_languageTagsList.push_front(defaultLocale); + } else { + LanguageTags::iterator placeToInsert = m_languageTagsList.end(); + --placeToInsert; + if (*placeToInsert != L"") { + ++placeToInsert; + } + m_languageTagsList.insert(placeToInsert, defaultLocale); + } + } +} + +DPL::String LanguageTagsProvider::BCP47LanguageTagToLocale( + const DPL::String& inLanguageTag) +{ + DPL::String languageTag(inLanguageTag); + /* Replace all */ + std::replace(languageTag.begin(), languageTag.end(), '-', '_'); + return languageTag; +} + +DPL::String LanguageTagsProvider::LocaleToBCP47LanguageTag( + const DPL::String& inLocaleString) +{ + /* Cut off codepage information from given string (if any exists) + * i.e. change en_US.UTF-8 into en_US */ + DPL::String localeString = inLocaleString.substr( + 0, inLocaleString.find_first_of(L".")); + /* Replace all '_' with '-' */ + std::replace(localeString.begin(), localeString.end(), '_', '-'); + return localeString; +} + +/* ========== private ========== */ +LanguageTagsProvider::LanguageTagsProvider() +{ + LogDebug("Creating LanguageTagsProvider instance"); + this->loadSystemTags(); +} + +LanguageTagsProvider::~LanguageTagsProvider() +{} + +void LanguageTagsProvider::loadSystemTags() +{ + char* language = vconf_get_str(VCONFKEY_LANGSET); + if (!language) { + LogError("Failed to get language from vconf"); + } else { + LogDebug("Language fetched from vconf: " << language); + } + createTagsFromLocales(language); + free(language); +} + +void LanguageTagsProvider::createTagsFromLocales(const char* language) +{ + m_languageTagsList.clear(); + if (!language) { + LogDebug("Setting default language tags"); + /* If NULL language given than set default language tags + * and return. */ + m_languageTagsList.push_back(L""); + return; + } + + LogDebug("Setting tags for language: " << language); + DPL::String langdescr = + LocaleToBCP47LanguageTag(DPL::FromUTF8String(language)); + + if (langdescr.empty()) { + LogError("Empty language description while correct value needed"); + } else { + /* Language tags list should not be cleared before this place to + * avoid losing current data when new data are invalid */ + size_t position; + while (true) { + LogDebug("Processing language description: " << langdescr); + m_languageTagsList.push_back(langdescr); + + // compatibility with lower language Tag by SDK + std::string langtag = DPL::ToUTF8String(langdescr); + std::transform(langtag.begin(), langtag.end(), langtag.begin(), ::tolower); + if (langtag != DPL::ToUTF8String(langdescr)) { + m_languageTagsList.push_back(DPL::FromUTF8String(langtag)); + } + + position = langdescr.find_last_of(L"-"); + if (position == DPL::String::npos) { + break; + } + langdescr = langdescr.substr(0, position); + } + } + /* Add empty tag for non-localized content */ + m_languageTagsList.push_back(L""); +} diff --git a/modules/localization/src/w3c_file_localization.cpp b/modules/localization/src/w3c_file_localization.cpp new file mode 100644 index 0000000..438c62b --- /dev/null +++ b/modules/localization/src/w3c_file_localization.cpp @@ -0,0 +1,575 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file w3c_file_localization.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + */ +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include + +using namespace WrtDB; + +namespace { +const DPL::String FILE_URI_BEGIN = L"file://"; +const DPL::String WIDGET_URI_BEGIN = L"widget://"; +const DPL::String APP_URI_BEGIN = L"app://"; +const DPL::String LOCALE_PREFIX = L"locales/"; + +DPL::Optional GetFilePathInWidgetPackageInternal( + const std::string& basePath, + std::string filePath) +{ + LogDebug("Looking for file: " << filePath << " in: " << basePath); + + const LanguageTags& ltags = + LanguageTagsProviderSingleton::Instance().getLanguageTags(); + + //Check if string isn't empty + if (filePath.size() == 0) { + return DPL::Optional::Null; + } + //Removing preceding '/' + if (filePath[0] == '/') { + filePath.erase(0, 1); + } + // In some cases (start file localization) url has unnecessary "/" at the + // end + if (filePath[filePath.size() - 1] == '/') { + filePath.erase(filePath.size() - 1, 1); + } + //Check if string isn't empty + if (filePath.size() == 0) { + return DPL::Optional::Null; + } + + LogDebug("locales size = " << ltags.size()); + for (LanguageTags::const_iterator it = ltags.begin(); + it != ltags.end(); + ++it) + { + LogDebug("Trying locale: " << *it); + std::string path = basePath; + if (path[path.size() - 1] == '/') { + path.erase(path.size() - 1); + } + + if (it->empty()) { + path += "/" + filePath; + } else { + path += "/locales/" + DPL::ToUTF8String(*it) + "/" + filePath; + } + + LogDebug("Trying locale: " << *it << " | " << path); + struct stat buf; + if (0 == stat(path.c_str(), &buf)) { + if ((buf.st_mode & S_IFMT) == S_IFREG) { + path.erase(0, basePath.length()); + return DPL::Optional(path); + } + } + } + + return DPL::Optional::Null; +} + +DPL::Optional GetFilePathInWidgetPackageInternal( + const DPL::String& basePath, + const DPL::String& filePath) +{ + DPL::Optional path = + GetFilePathInWidgetPackageInternal(DPL::ToUTF8String(basePath), + DPL::ToUTF8String(filePath)); + DPL::Optional dplPath; + if (!!path) { + dplPath = DPL::FromUTF8String(*path); + } + return dplPath; +} +} + +namespace W3CFileLocalization { +static bool isExistFileCached(const std::string& path) +{ + static std::map pathCache; + + // is cached? + if (pathCache.find(path) == pathCache.end()) + { + struct stat buf; + + if (0 == stat(path.c_str(), &buf)) + { + pathCache[path] = true; + + return true; + } + else + { + pathCache[path] = false; + + return false; + } + } + + return pathCache[path]; +} + +std::string getFilePathInWidgetPackageFromUrl(const std::string &tzAppId, const std::string &url) +{ + const std::string SCHEME_FILE = "file://"; + const std::string SCHEME_WIDGET = "widget://"; + const std::string SCHEM_APP = "app://"; + const std::string LOCALE_PATH = "locales/"; + const std::string DOUBLE_ROOT = "//"; + + static std::string lastTzAppId; + static WidgetDAOReadOnlyPtr dao; + static std::string srcPath; + + std::string workingUrl = url; + bool found = false; + + // Dao caching + if (lastTzAppId != tzAppId) + { + lastTzAppId = tzAppId; + dao.reset(new WidgetDAOReadOnly(DPL::FromUTF8String(tzAppId))); + srcPath = DPL::ToUTF8String(dao->getPath()); + } + + // backup suffix string + std::string backupSuffix; + size_t pos = workingUrl.find_first_of("#?"); + + if (pos != std::string::npos) + { + backupSuffix = workingUrl.substr(pos); + workingUrl.resize(pos); + } + + // make basis path + if (workingUrl.compare(0, SCHEME_WIDGET.length(), SCHEME_WIDGET) == 0) + { + // remove "widget://" + workingUrl.erase(0, SCHEME_WIDGET.length()); + } + else if (workingUrl.compare(0, SCHEME_FILE.length(), SCHEME_FILE) == 0) + { + // remove "file://" + workingUrl.erase(0, SCHEME_FILE.length()); + + // exception handling for "//" + if (workingUrl.compare(0, DOUBLE_ROOT.length(), DOUBLE_ROOT) == 0) + { + workingUrl.erase(0, 1); + LogDebug("workingUrl: " << workingUrl); + } + + // remove src path + if (workingUrl.compare(0, srcPath.length(), srcPath) == 0) + { + workingUrl.erase(0, srcPath.length()); + } + + // remove locale path + if (workingUrl.compare(0, LOCALE_PATH.length(), LOCALE_PATH) == 0) + { + workingUrl.erase(0, LOCALE_PATH.length()); + + pos = workingUrl.find_first_of('/'); + + if (pos != std::string::npos && pos > 0) + { + workingUrl.erase(0, pos+1); + } + } + } + else if (workingUrl.compare(0, SCHEM_APP.length(), SCHEM_APP) == 0) + { + // remove "app://" + workingUrl.erase(0, SCHEM_APP.length()); + + // remove tizen app id + if (workingUrl.compare(0, tzAppId.length(), tzAppId) == 0) + { + workingUrl.erase(0, tzAppId.length()); + } + else + { + LogError("Tizen id does not match, ignoring"); + return ""; + } + } + + // remove '/' token + if (!workingUrl.empty() && workingUrl[0] == '/') + { + workingUrl.erase(0, 1); + } + + if (!workingUrl.empty() && workingUrl[workingUrl.length()-1] == '/') { + workingUrl.erase(workingUrl.length()-1, 1); + } + + if (workingUrl.empty()) + { + LogError("URL Localization Error!"); + return ""; + } + + const LanguageTags& ltags = LanguageTagsProviderSingleton::Instance().getLanguageTags(); + + FOREACH(it, ltags) + { + std::string path = srcPath; + + if (!it->empty()) + { + path += LOCALE_PATH; + + if (isExistFileCached(path) == false) + { + continue; + } + + path += DPL::ToUTF8String(*it) + "/"; + + if (isExistFileCached(path) == false) + { + continue; + } + } + + path += workingUrl; + + if (isExistFileCached(path) == true) + { + found = true; + workingUrl = path; + break; + } + } + + // restore suffix string + if (!found) + { + // return empty string + workingUrl = ""; + } + else + { + if (!backupSuffix.empty()) + { + workingUrl += backupSuffix; + } + } + + return workingUrl; +} + +DPL::Optional getFilePathInWidgetPackageFromUrl( + const WrtDB::TizenAppId &tzAppId, + const DPL::String &url) +{ + return getFilePathInWidgetPackageFromUrl( + WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)), + url); +} + +DPL::Optional getFilePathInWidgetPackageFromUrl( + WrtDB::WidgetDAOReadOnlyPtr dao, + const DPL::String &url) +{ + DPL::String req = url; + + DPL::String suffix; + DPL::String::size_type pos = req.find_first_of('#'); + if(pos != DPL::String::npos) + { + suffix = req.substr(pos) + suffix; + req.resize(pos); //truncate fragment identifier + } + + pos = req.find_first_of('?'); + if(pos != DPL::String::npos) + { + suffix = req.substr(pos) + suffix; + req.resize(pos); //truncate query string + } + + if (req.find(WIDGET_URI_BEGIN) == 0) { + req.erase(0, WIDGET_URI_BEGIN.length()); + } else if (req.find(FILE_URI_BEGIN) == 0) { + req.erase(0, FILE_URI_BEGIN.length()); + if (req.find(dao->getPath()) == 0) { + req.erase(0, dao->getPath().length()); + } + if (req.find(LOCALE_PREFIX) == 0) { + req.erase(0, LOCALE_PREFIX.length()); + size_t position = req.find('/'); + // should always be >0 as correct locales path is + // always locales/xx/ or locales/xx-XX/ + if (position != std::string::npos && position > 0) { + req.erase(0, position + 1); + } + } + } else if(req.find(APP_URI_BEGIN) == 0) { + req.erase(0, APP_URI_BEGIN.length()); + DPL::String id = dao->getTizenAppId(); + if(req.substr(0, id.size()) != id) + { + LogError("Tizen id does not match, ignoring"); + return DPL::Optional::Null; + } + req.erase(0, id.length()); + } else { + LogDebug("Unknown path format, ignoring"); + return DPL::Optional::Null; + } + + auto widgetPath = dao->getPath(); + + LogDebug("Required path: " << req); + DPL::Optional found = + GetFilePathInWidgetPackageInternal(widgetPath, req); + + if (!found) { + LogError("Path not found within current locale in current widget"); + return DPL::Optional::Null; + } + + found = widgetPath + *found + suffix; + + return found; +} + +DPL::Optional getFilePathInWidgetPackage( + const WrtDB::TizenAppId &tzAppId, + const DPL::String& file) +{ + return getFilePathInWidgetPackage( + WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)), + file); +} + +DPL::Optional getFilePathInWidgetPackage( + WrtDB::WidgetDAOReadOnlyPtr dao, + const DPL::String& file) +{ + return GetFilePathInWidgetPackageInternal(dao->getPath(), file); +} + +DPL::OptionalString getStartFile(const WrtDB::TizenAppId & tzAppId) +{ + return getStartFile(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId))); +} + +DPL::OptionalString getStartFile(WrtDB::WidgetDAOReadOnlyPtr dao) +{ + WidgetDAOReadOnly::LocalizedStartFileList locList = + dao->getLocalizedStartFileList(); + WidgetDAOReadOnly::WidgetStartFileList list = dao->getStartFileList(); + LanguageTags tagsList = + LanguageTagsProviderSingleton::Instance().getLanguageTags(); + + DPL::OptionalString defaultLoc = dao->getDefaultlocale(); + if (!!defaultLoc) { + tagsList.push_back(*defaultLoc); + } + + FOREACH(tag, tagsList) + { + FOREACH(sFile, locList) + { + if (*tag == sFile->widgetLocale) { + FOREACH(it, list) + { + if (it->startFileId == sFile->startFileId) { + return it->src; + } + } + } + } + } + + return DPL::OptionalString::Null; +} + +OptionalWidgetIcon getIcon(const WrtDB::TizenAppId & tzAppId) +{ + return getIcon(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId))); +} + +OptionalWidgetIcon getIcon(WrtDB::WidgetDAOReadOnlyPtr dao) +{ + WidgetDAOReadOnly::WidgetLocalizedIconList locList = + dao->getLocalizedIconList(); + WidgetDAOReadOnly::WidgetIconList list = dao->getIconList(); + LanguageTags tagsList = + LanguageTagsProviderSingleton::Instance().getLanguageTags(); + + DPL::OptionalString defaultLoc = dao->getDefaultlocale(); + if (!!defaultLoc) { + tagsList.push_back(*defaultLoc); + } + + FOREACH(tag, tagsList) + { + FOREACH(icon, locList) + { + if (*tag == icon->widgetLocale) { + FOREACH(it, list) + { + if (it->iconId == icon->iconId) { + WidgetIcon ret; + ret.src = it->iconSrc; + ret.width = it->iconWidth; + ret.height = it->iconHeight; + return ret; + } + } + } + } + } + + return OptionalWidgetIcon::Null; +} + +WidgetIconList getValidIconsList(const WrtDB::TizenAppId &tzAppId) +{ + return getValidIconsList( + WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId))); +} + +WidgetIconList getValidIconsList(WrtDB::WidgetDAOReadOnlyPtr dao) +{ + WidgetDAOReadOnly::WidgetIconList list = dao->getIconList(); + + WidgetIconList outlist; + + FOREACH(it, list) + { + LogDebug(":" << it->iconSrc); + if (!!getFilePathInWidgetPackage(dao->getTizenAppId(), + it->iconSrc)) + { + WidgetIcon ret; + ret.src = it->iconSrc; + ret.width = it->iconWidth; + ret.height = it->iconHeight; + outlist.push_back(ret); + } + } + return outlist; +} + +OptionalWidgetStartFileInfo getStartFileInfo( + const WrtDB::TizenAppId &tzAppId) +{ + return getStartFileInfo( + WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId))); +} + +OptionalWidgetStartFileInfo getStartFileInfo(WrtDB::WidgetDAOReadOnlyPtr dao) +{ + WidgetStartFileInfo info; + + WidgetDAOReadOnly::LocalizedStartFileList locList = + dao->getLocalizedStartFileList(); + WidgetDAOReadOnly::WidgetStartFileList list = dao->getStartFileList(); + const LanguageTags tagsList = + LanguageTagsProviderSingleton::Instance().getLanguageTags(); + + FOREACH(tag, tagsList) + { + FOREACH(sFile, locList) + { + if (*tag == sFile->widgetLocale) { + FOREACH(it, list) + { + if (it->startFileId == + sFile->startFileId) + { + info.file = it->src; + info.encoding = sFile->encoding; + info.type = sFile->type; + if (tag->empty()) { + info.localizedPath = it->src; + } else { + info.localizedPath = L"locales/" + *tag + L"/"; + info.localizedPath += it->src; + } + return info; + } + } + } + } + } + + return OptionalWidgetStartFileInfo::Null; +} + +WidgetLocalizedInfo getLocalizedInfo(const WrtDB::TizenAppId & tzAppId) +{ + return getLocalizedInfo(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId))); +} + +WidgetLocalizedInfo getLocalizedInfo(WidgetDAOReadOnlyPtr dao) +{ + LanguageTags languages = + LanguageTagsProviderSingleton::Instance().getLanguageTags(); + DPL::OptionalString dl = dao->getDefaultlocale(); + if (!!dl) { + languages.push_back(*dl); + } + + WidgetLocalizedInfo result; + FOREACH(i, languages) + { + WidgetLocalizedInfo languageResult = dao->getLocalizedInfo(*i); + +#define OVERWRITE_IF_NULL(FIELD) if (!result.FIELD) { \ + result.FIELD = languageResult.FIELD; \ +} + + OVERWRITE_IF_NULL(name); + OVERWRITE_IF_NULL(shortName); + OVERWRITE_IF_NULL(description); + OVERWRITE_IF_NULL(license); + OVERWRITE_IF_NULL(licenseHref); + +#undef OVERWRITE_IF_NULL + } + + return result; +} +} diff --git a/modules/log/config.cmake b/modules/log/config.cmake new file mode 100644 index 0000000..30ad033 --- /dev/null +++ b/modules/log/config.cmake @@ -0,0 +1,42 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_LOG_SOURCES + ${PROJECT_SOURCE_DIR}/modules/log/src/abstract_log_provider.cpp + ${PROJECT_SOURCE_DIR}/modules/log/src/dlog_log_provider.cpp + ${PROJECT_SOURCE_DIR}/modules/log/src/log.cpp + ${PROJECT_SOURCE_DIR}/modules/log/src/old_style_log_provider.cpp + PARENT_SCOPE +) + +SET(DPL_LOG_HEADERS + ${PROJECT_SOURCE_DIR}/modules/log/include/dpl/log/abstract_log_provider.h + ${PROJECT_SOURCE_DIR}/modules/log/include/dpl/log/dlog_log_provider.h + ${PROJECT_SOURCE_DIR}/modules/log/include/dpl/log/log.h + ${PROJECT_SOURCE_DIR}/modules/log/include/dpl/log/old_style_log_provider.h + ${PROJECT_SOURCE_DIR}/modules/log/include/dpl/log/secure_log.h + PARENT_SCOPE +) + +SET(DPL_LOG_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/log/include/ + PARENT_SCOPE +) diff --git a/modules/log/include/dpl/log/abstract_log_provider.h b/modules/log/include/dpl/log/abstract_log_provider.h new file mode 100644 index 0000000..62fa050 --- /dev/null +++ b/modules/log/include/dpl/log/abstract_log_provider.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_log_provider.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract log provider + */ +#ifndef DPL_ABSTRACT_LOG_PROVIDER_H +#define DPL_ABSTRACT_LOG_PROVIDER_H + +namespace DPL { +namespace Log { +class AbstractLogProvider +{ + public: + virtual ~AbstractLogProvider() {} + + virtual void Debug(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void Info(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void Warning(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void Error(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void Pedantic(const char *message, + const char *fileName, + int line, + const char *function) = 0; + + protected: + static const char *LocateSourceFileName(const char *filename); +}; +} +} // namespace DPL + +#endif // DPL_ABSTRACT_LOG_PROVIDER_H diff --git a/modules/log/include/dpl/log/dlog_log_provider.h b/modules/log/include/dpl/log/dlog_log_provider.h new file mode 100644 index 0000000..1dd4c2d --- /dev/null +++ b/modules/log/include/dpl/log/dlog_log_provider.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dlog_log_provider.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of DLOG log provider + */ +#ifndef DPL_DLOG_LOG_PROVIDER_H +#define DPL_DLOG_LOG_PROVIDER_H + +#include +#include +#include + +namespace DPL { +namespace Log { +class DLOGLogProvider : + public AbstractLogProvider +{ + private: + DPL::ScopedFree m_tag; + + static std::string FormatMessage(const char *message, + const char *filename, + int line, + const char *function); + + public: + DLOGLogProvider(); + virtual ~DLOGLogProvider(); + + virtual void Debug(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Info(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Warning(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Error(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Pedantic(const char *message, + const char *fileName, + int line, + const char *function); + + // Set global Tag according to DLOG + void SetTag(const char *tag); +}; +} +} // namespace DPL + +#endif // DPL_DLOG_LOG_PROVIDER_H diff --git a/modules/log/include/dpl/log/log.h b/modules/log/include/dpl/log/log.h new file mode 100644 index 0000000..d4d95ed --- /dev/null +++ b/modules/log/include/dpl/log/log.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file log.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of log system + */ +#ifndef DPL_LOG_H +#define DPL_LOG_H + +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Log { +/** + * DPL log system + * + * To switch logs into old style, export + * DPL_USE_OLD_STYLE_LOGS before application start + */ +class LogSystem : + private Noncopyable +{ + private: + typedef std::list AbstractLogProviderPtrList; + AbstractLogProviderPtrList m_providers; + + DLOGLogProvider *m_dlogProvider; + OldStyleLogProvider *m_oldStyleProvider; + + bool m_isLoggingEnabled; + + public: + bool IsLoggingEnabled() const; + LogSystem(); + virtual ~LogSystem(); + + /** + * Log debug message + */ + void Debug(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log info message + */ + void Info(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log warning message + */ + void Warning(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log error message + */ + void Error(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log pedantic message + */ + void Pedantic(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Set default's DLOG provider Tag + */ + void SetTag(const char *tag); + + /** + * Add abstract provider to providers list + * + * @notice Ownership is transfered to LogSystem and deleted upon exit + */ + void AddProvider(AbstractLogProvider *provider); + + /** + * Remove abstract provider from providers list + */ + void RemoveProvider(AbstractLogProvider *provider); +}; + +/* + * Replacement low overhead null logging class + */ +class NullStream +{ + public: + NullStream() {} + + template + NullStream& operator<<(const T&) + { + return *this; + } +}; + +/** + * Log system singleton + */ +typedef Singleton LogSystemSingleton; +} +} // namespace DPL + +// +// Log support +// +// + +#ifdef DPL_LOGS_ENABLED + #define DPL_MACRO_FOR_LOGGING(message, function) \ + do \ + { \ + if (DPL::Log::LogSystemSingleton::Instance().IsLoggingEnabled()) \ + { \ + std::ostringstream platformLog; \ + platformLog << message; \ + DPL::Log::LogSystemSingleton::Instance().function( \ + platformLog.str().c_str(), \ + __FILE__, __LINE__, __FUNCTION__); \ + } \ + } while (0) +#else +/* avoid warnings about unused variables */ + #define DPL_MACRO_FOR_LOGGING(message, function) \ + do { \ + DPL::Log::NullStream ns; \ + ns << message; \ + } while (0) +#endif + +#define LogDebug(message) DPL_MACRO_FOR_LOGGING(message, Debug) +#define LogInfo(message) DPL_MACRO_FOR_LOGGING(message, Info) +#define LogWarning(message) DPL_MACRO_FOR_LOGGING(message, Warning) +#define LogError(message) DPL_MACRO_FOR_LOGGING(message, Error) +#define LogPedantic(message) DPL_MACRO_FOR_LOGGING(message, Pedantic) + +#endif // DPL_LOG_H diff --git a/modules/log/include/dpl/log/old_style_log_provider.h b/modules/log/include/dpl/log/old_style_log_provider.h new file mode 100644 index 0000000..70e308a --- /dev/null +++ b/modules/log/include/dpl/log/old_style_log_provider.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file old_style_log_provider.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of old style log provider + */ +#ifndef DPL_OLD_STYLE_LOG_PROVIDER_H +#define DPL_OLD_STYLE_LOG_PROVIDER_H + +#include +#include + +namespace DPL { +namespace Log { +class OldStyleLogProvider : + public AbstractLogProvider +{ + private: + bool m_showDebug; + bool m_showInfo; + bool m_showWarning; + bool m_showError; + bool m_showPedantic; + bool m_printStdErr; + + static std::string FormatMessage(const char *message, + const char *filename, + int line, + const char *function); + + public: + OldStyleLogProvider(bool showDebug, + bool showInfo, + bool showWarning, + bool showError, + bool showPedantic); + OldStyleLogProvider(bool showDebug, + bool showInfo, + bool showWarning, + bool showError, + bool showPedantic, + bool printStdErr); + virtual ~OldStyleLogProvider() {} + + virtual void Debug(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Info(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Warning(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Error(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Pedantic(const char *message, + const char *fileName, + int line, + const char *function); +}; +} +} // namespace DPL + +#endif // DPL_OLD_STYLE_LOG_PROVIDER_H diff --git a/modules/log/include/dpl/log/secure_log.h b/modules/log/include/dpl/log/secure_log.h new file mode 100644 index 0000000..6402c4f --- /dev/null +++ b/modules/log/include/dpl/log/secure_log.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file secure_log.h + * @author Jihoon Chung(jihoon.chung@samsung.com) + * @version 0.1 + * @brief + */ + +#ifndef DPL_SECURE_LOG_H +#define DPL_SECURE_LOG_H + +#include + +#define COLOR_ERROR "\e[1;31m" +#define COLOR_WARNING "\e[2;31m" +#define COLOR_END "\e[0m" +#define COLOR_TAG "\e[0m" + +// default TAG +#undef LOG_TAG +#define LOG_TAG "WRT_UNDEFINED" + +#ifdef WRT_LOG +#undef LOG_TAG +#define LOG_TAG "WRT" +#undef COLOR_TAG +#define COLOR_TAG "\e[1;32m" +#endif + +#ifdef WRT_BUNDLE_LOG +#undef LOG_TAG +#define LOG_TAG "WRT_BUNDLE" +#undef COLOR_TAG +#define COLOR_TAG "\e[1;34m" +#endif + +#ifdef WRT_PLUGINS_COMMON_LOG +#undef LOG_TAG +#define LOG_TAG "WRT_PLUGINS/COMMON" +#undef COLOR_TAG +#define COLOR_TAG "\e[1;36m" +#endif + +#ifdef WRT_PLUGINS_WIDGET_LOG +#undef LOG_TAG +#define LOG_TAG "WRT_PLUGINS/WIDGET" +#undef COLOR_TAG +#define COLOR_TAG "\e[1;35m" +#endif + +#ifdef WRT_INSTALLER_LOG +#undef LOG_TAG +#define LOG_TAG "WRT_INSTALLER" +#undef COLOR_TAG +#define COLOR_TAG "\e[1;32m" +#endif + +#ifndef SECURE_SLOGD +#define SECURE_SLOGD(fmt, arg...) SLOGD(fmt,##arg) +#endif + +#ifndef SECURE_SLOGW +#define SECURE_SLOGW(fmt, arg...) SLOGW(fmt,##arg) +#endif + +#ifndef SECURE_SLOGE +#define SECURE_SLOGE(fmt, arg...) SLOGE(fmt,##arg) +#endif + +#undef _D +#define _D(fmt, arg ...) SECURE_SLOGD(COLOR_TAG fmt COLOR_END,##arg) +#undef _W +#define _W(fmt, arg ...) SECURE_SLOGW(COLOR_WARNING fmt COLOR_END,##arg) +#undef _E +#define _E(fmt, arg ...) SECURE_SLOGE(COLOR_ERROR fmt COLOR_END,##arg) + +#endif // DPL_SECURE_LOG_H + diff --git a/modules/log/src/abstract_log_provider.cpp b/modules/log/src/abstract_log_provider.cpp new file mode 100644 index 0000000..a03f8a0 --- /dev/null +++ b/modules/log/src/abstract_log_provider.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_log_provider.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract log provider + */ +#include +#include +#include + +namespace DPL { +namespace Log { +const char *AbstractLogProvider::LocateSourceFileName(const char *filename) +{ + const char *ptr = strrchr(filename, '/'); + return ptr != NULL ? ptr + 1 : filename; +} +} +} diff --git a/modules/log/src/dlog_log_provider.cpp b/modules/log/src/dlog_log_provider.cpp new file mode 100644 index 0000000..1a203db --- /dev/null +++ b/modules/log/src/dlog_log_provider.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dlog_log_provider.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of DLOG log provider + */ +#include +#include +#include +#include +#include + +#ifdef SECURE_LOG + #define INTERNAL_DLP_LOG_ SECURE_LOG +#else + #define INTERNAL_DLP_LOG_ LOG +#endif + +/* + * The __extension__ keyword in the following define is required because + * macros used here from dlog.h use non-standard extension that cause + * gcc to show unwanted warnings when compiling with -pedantic switch. + */ +#define INTERNAL_DLP_LOG __extension__ INTERNAL_DLP_LOG_ + +namespace DPL { +namespace Log { +std::string DLOGLogProvider::FormatMessage(const char *message, + const char *filename, + int line, + const char *function) +{ + std::ostringstream val; + + val << std::string("[") << + LocateSourceFileName(filename) << std::string(":") << line << + std::string("] ") << function << std::string("(): ") << message; + + return val.str(); +} + +DLOGLogProvider::DLOGLogProvider() +{} + +DLOGLogProvider::~DLOGLogProvider() +{} + +void DLOGLogProvider::SetTag(const char *tag) +{ + m_tag.Reset(strdup(tag)); +} + +void DLOGLogProvider::Debug(const char *message, + const char *filename, + int line, + const char *function) +{ + INTERNAL_DLP_LOG(LOG_DEBUG, m_tag.Get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::Info(const char *message, + const char *filename, + int line, + const char *function) +{ + INTERNAL_DLP_LOG(LOG_INFO, m_tag.Get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::Warning(const char *message, + const char *filename, + int line, + const char *function) +{ + INTERNAL_DLP_LOG(LOG_WARN, m_tag.Get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::Error(const char *message, + const char *filename, + int line, + const char *function) +{ + INTERNAL_DLP_LOG(LOG_ERROR, m_tag.Get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::Pedantic(const char *message, + const char *filename, + int line, + const char *function) +{ + INTERNAL_DLP_LOG(LOG_DEBUG, "DPL", "%s", + FormatMessage(message, filename, line, function).c_str()); +} +} +} // namespace DPL + +#undef INTERNAL_DLP_LOG +#undef INTERNAL_DLP_LOG_ + diff --git a/modules/log/src/log.cpp b/modules/log/src/log.cpp new file mode 100644 index 0000000..7c0ebc2 --- /dev/null +++ b/modules/log/src/log.cpp @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file log.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of log system + */ +#include +#include +#include + +IMPLEMENT_SINGLETON(DPL::Log::LogSystem) + +namespace DPL { +namespace Log { +namespace // anonymous +{ +const char *OLD_STYLE_LOGS_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS"; +const char *OLD_STYLE_PEDANTIC_LOGS_ENV_NAME = + "DPL_USE_OLD_STYLE_PEDANTIC_LOGS"; +const char *OLD_STYLE_LOGS_MASK_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS_MASK"; +const char *DPL_LOG_OFF = "DPL_LOG_OFF"; +} // namespace anonymous + +bool LogSystem::IsLoggingEnabled() const +{ + return m_isLoggingEnabled; +} + +LogSystem::LogSystem() : + m_dlogProvider(NULL), + m_oldStyleProvider(NULL), + m_isLoggingEnabled(!getenv(DPL_LOG_OFF)) +{ + bool oldStyleLogs = false; + bool oldStyleDebugLogs = true; + bool oldStyleInfoLogs = true; + bool oldStyleWarningLogs = true; + bool oldStyleErrorLogs = true; + bool oldStylePedanticLogs = false; + + // Check environment settings about pedantic logs + const char *value = getenv(OLD_STYLE_LOGS_ENV_NAME); + + if (value != NULL && !strcmp(value, "1")) { + oldStyleLogs = true; + } + + value = getenv(OLD_STYLE_PEDANTIC_LOGS_ENV_NAME); + + if (value != NULL && !strcmp(value, "1")) { + oldStylePedanticLogs = true; + } + + value = getenv(OLD_STYLE_LOGS_MASK_ENV_NAME); + + if (value != NULL) { + size_t len = strlen(value); + + if (len >= 1) { + if (value[0] == '0') { + oldStyleDebugLogs = false; + } else if (value[0] == '1') { + oldStyleDebugLogs = true; + } + } + + if (len >= 2) { + if (value[1] == '0') { + oldStyleInfoLogs = false; + } else if (value[1] == '1') { + oldStyleInfoLogs = true; + } + } + + if (len >= 3) { + if (value[2] == '0') { + oldStyleWarningLogs = false; + } else if (value[2] == '1') { + oldStyleWarningLogs = true; + } + } + + if (len >= 4) { + if (value[3] == '0') { + oldStyleErrorLogs = false; + } else if (value[3] == '1') { + oldStyleErrorLogs = true; + } + } + } + + // Setup default DLOG and old style logging + if (oldStyleLogs) { + // Old style + m_oldStyleProvider = new OldStyleLogProvider(oldStyleDebugLogs, + oldStyleInfoLogs, + oldStyleWarningLogs, + oldStyleErrorLogs, + oldStylePedanticLogs); + AddProvider(m_oldStyleProvider); + } else { + // DLOG + m_dlogProvider = new DLOGLogProvider(); + AddProvider(m_dlogProvider); + } +} + +LogSystem::~LogSystem() +{ + // Delete all providers + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + delete *iterator; + } + + m_providers.clear(); + + // And even default providers + m_dlogProvider = NULL; + m_oldStyleProvider = NULL; +} + +void LogSystem::SetTag(const char* tag) +{ + if (m_dlogProvider != NULL) { + m_dlogProvider->SetTag(tag); + } +} + +void LogSystem::AddProvider(AbstractLogProvider *provider) +{ + m_providers.push_back(provider); +} + +void LogSystem::RemoveProvider(AbstractLogProvider *provider) +{ + m_providers.remove(provider); +} + +void LogSystem::Debug(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->Debug(message, filename, line, function); + } +} + +void LogSystem::Info(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->Info(message, filename, line, function); + } +} + +void LogSystem::Warning(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->Warning(message, filename, line, function); + } +} + +void LogSystem::Error(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->Error(message, filename, line, function); + } +} + +void LogSystem::Pedantic(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->Pedantic(message, filename, line, function); + } +} +} +} // namespace DPL diff --git a/modules/log/src/old_style_log_provider.cpp b/modules/log/src/old_style_log_provider.cpp new file mode 100644 index 0000000..b8060dd --- /dev/null +++ b/modules/log/src/old_style_log_provider.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file old_style_log_provider.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of old style log provider + */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Log { +namespace // anonymous +{ +using namespace DPL::Colors::Text; +const char *DEBUG_BEGIN = GREEN_BEGIN; +const char *DEBUG_END = GREEN_END; +const char *INFO_BEGIN = CYAN_BEGIN; +const char *INFO_END = CYAN_END; +const char *ERROR_BEGIN = RED_BEGIN; +const char *ERROR_END = RED_END; +const char *WARNING_BEGIN = BOLD_GOLD_BEGIN; +const char *WARNING_END = BOLD_GOLD_END; +const char *PEDANTIC_BEGIN = PURPLE_BEGIN; +const char *PEDANTIC_END = PURPLE_END; + +std::string GetFormattedTime() +{ + timeval tv; + tm localNowTime; + + gettimeofday(&tv, NULL); + localtime_r(&tv.tv_sec, &localNowTime); + + char format[64]; + snprintf(format, + sizeof(format), + "%02i:%02i:%02i.%03i", + localNowTime.tm_hour, + localNowTime.tm_min, + localNowTime.tm_sec, + static_cast(tv.tv_usec / 1000)); + return format; +} +} // namespace anonymous + +std::string OldStyleLogProvider::FormatMessage(const char *message, + const char *filename, + int line, + const char *function) +{ + std::ostringstream val; + + val << std::string("[") << GetFormattedTime() << std::string("] [") << + static_cast(pthread_self()) << "/" << + static_cast(getpid()) << std::string("] [") << + LocateSourceFileName(filename) << std::string(":") << line << + std::string("] ") << function << std::string("(): ") << message; + + return val.str(); +} + +OldStyleLogProvider::OldStyleLogProvider(bool showDebug, + bool showInfo, + bool showWarning, + bool showError, + bool showPedantic) : + m_showDebug(showDebug), + m_showInfo(showInfo), + m_showWarning(showWarning), + m_showError(showError), + m_showPedantic(showPedantic), + m_printStdErr(false) +{} + +OldStyleLogProvider::OldStyleLogProvider(bool showDebug, + bool showInfo, + bool showWarning, + bool showError, + bool showPedantic, + bool printStdErr) : + m_showDebug(showDebug), + m_showInfo(showInfo), + m_showWarning(showWarning), + m_showError(showError), + m_showPedantic(showPedantic), + m_printStdErr(printStdErr) +{} + +void OldStyleLogProvider::Debug(const char *message, + const char *filename, + int line, + const char *function) +{ + if (m_showDebug) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", DEBUG_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), DEBUG_END); + } else { + fprintf(stdout, "%s%s%s\n", DEBUG_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), DEBUG_END); + } + } +} + +void OldStyleLogProvider::Info(const char *message, + const char *filename, + int line, + const char *function) +{ + if (m_showInfo) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", INFO_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), INFO_END); + } else { + fprintf(stdout, "%s%s%s\n", INFO_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), INFO_END); + } + } +} + +void OldStyleLogProvider::Warning(const char *message, + const char *filename, + int line, + const char *function) +{ + if (m_showWarning) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", WARNING_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), WARNING_END); + } else { + fprintf(stdout, "%s%s%s\n", WARNING_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), WARNING_END); + } + } +} + +void OldStyleLogProvider::Error(const char *message, + const char *filename, + int line, + const char *function) +{ + if (m_showError) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", ERROR_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), ERROR_END); + } else { + fprintf(stdout, "%s%s%s\n", ERROR_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), ERROR_END); + } + } +} + +void OldStyleLogProvider::Pedantic(const char *message, + const char *filename, + int line, + const char *function) +{ + if (m_showPedantic) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", PEDANTIC_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), PEDANTIC_END); + } else { + fprintf(stdout, "%s%s%s\n", PEDANTIC_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), PEDANTIC_END); + } + } +} +} +} // namespace DPL diff --git a/modules/rpc/config.cmake b/modules/rpc/config.cmake new file mode 100644 index 0000000..9f3d810 --- /dev/null +++ b/modules/rpc/config.cmake @@ -0,0 +1,52 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_RPC_SOURCES + ${PROJECT_SOURCE_DIR}/modules/rpc/src/abstract_rpc_connection.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/abstract_rpc_connector.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/generic_rpc_connection.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/generic_socket_rpc_client.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/generic_socket_rpc_connection.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/generic_socket_rpc_server.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/unix_socket_rpc_client.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/unix_socket_rpc_connection.cpp + ${PROJECT_SOURCE_DIR}/modules/rpc/src/unix_socket_rpc_server.cpp + PARENT_SCOPE +) + +SET(DPL_RPC_HEADERS + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/abstract_rpc_connection.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/abstract_rpc_connector.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/generic_rpc_connection.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/generic_socket_rpc_client.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/generic_socket_rpc_connection.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/generic_socket_rpc_server.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/rpc_function.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/unix_socket_rpc_client.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/unix_socket_rpc_connection.h + ${PROJECT_SOURCE_DIR}/modules/rpc/include/dpl/rpc/unix_socket_rpc_server.h + PARENT_SCOPE +) + +SET(DPL_RPC_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/rpc/include + PARENT_SCOPE +) diff --git a/modules/rpc/include/dpl/rpc/abstract_rpc_connection.h b/modules/rpc/include/dpl/rpc/abstract_rpc_connection.h new file mode 100644 index 0000000..7857c60 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/abstract_rpc_connection.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_rpc_connection.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for abstract RPC connection + */ +#ifndef DPL_ABSTRACT_RPC_CONNECTION_H +#define DPL_ABSTRACT_RPC_CONNECTION_H + +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace RPC { +namespace AbstractRPCConnectionEvents { +/** + * Asynchronous call event + */ +DECLARE_GENERIC_EVENT_1(AsyncCallEvent, RPCFunction) + +/** + * Connection closed event + */ +DECLARE_GENERIC_EVENT_0(ConnectionClosedEvent) + +/** + * Connection broken event + */ +DECLARE_GENERIC_EVENT_0(ConnectionBrokenEvent) +} // namespace AbstractRPCConnectionEvents + +class AbstractRPCConnection : + public DPL::Event::EventSupport, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, AsyncCallFailed) + DECLARE_EXCEPTION_TYPE(Base, PingFailed) + }; + + public: + virtual ~AbstractRPCConnection() {} + + /** + * Call asynchronously RPC function + * + * @param function COnstant reference to RPC function to call + * @return none + */ + virtual void AsyncCall(const RPCFunction &function) = 0; + + /** + * Ping RPC connection + * This will send a ping/pong packet over connection to ensure it is alive + * If any errors are to occur proper events will be emitted + * + * @return none + */ + virtual void Ping() = 0; +}; + +/** + * Abstract connection ID used to represent connection being established + * or RPC server accepting connection + */ +typedef void *AbstractRPCConnectionID; +} +} // namespace DPL + +#endif // DPL_ABSTRACT_RPC_CONNECTION_H diff --git a/modules/rpc/include/dpl/rpc/abstract_rpc_connector.h b/modules/rpc/include/dpl/rpc/abstract_rpc_connector.h new file mode 100644 index 0000000..c9e3b1f --- /dev/null +++ b/modules/rpc/include/dpl/rpc/abstract_rpc_connector.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_rpc_connector.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for abstract RPC connector + */ +#ifndef DPL_ABSTRACT_RPC_CONNECTOR_H +#define DPL_ABSTRACT_RPC_CONNECTOR_H + +#include +#include +#include + +namespace DPL { +namespace RPC { +namespace AbstractRPCConnectorEvents { +/** + * RPC connection established + */ +DECLARE_GENERIC_EVENT_2(ConnectionEstablishedEvent, + AbstractRPCConnectionID, + AbstractRPCConnection *) +} // namespace AbstractRPCClientEvents + +class AbstractRPCConnector : + public DPL::Event::EventSupport +{ + public: + /** + * Destructor + */ + virtual ~AbstractRPCConnector() {} +}; +} +} // namespace DPL + +#endif // DPL_ABSTRACT_RPC_CONNECTOR_H diff --git a/modules/rpc/include/dpl/rpc/generic_rpc_connection.h b/modules/rpc/include/dpl/rpc/generic_rpc_connection.h new file mode 100644 index 0000000..d9614c6 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/generic_rpc_connection.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_rpc_connection.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for generic RPC connection + */ +#ifndef DPL_GENERIC_RPC_CONNECTION_H +#define DPL_GENERIC_RPC_CONNECTION_H + +#include +#include +#include +#include + +namespace DPL { +namespace RPC { +class GenericRPCConnection : + public AbstractRPCConnection, + private DPL::Socket::WaitableInputOutputExecutionContextSupport +{ + private: + // WaitableInputOutputExecutionContextSupport + virtual void OnInputStreamRead(); + virtual void OnInputStreamClosed(); + virtual void OnInputStreamBroken(); + + std::unique_ptr m_inputOutput; + + public: + /** + * Costructor + * + * Abstract waitable input/outobject is acquired by class and destroyed upon + * destructor + */ + explicit GenericRPCConnection(AbstractWaitableInputOutput *inputOutput); + virtual ~GenericRPCConnection(); + + virtual void AsyncCall(const RPCFunction &function); + virtual void Ping(); +}; +} +} // namespace DPL + +#endif // DPL_GENERIC_RPC_CONNECTION_H diff --git a/modules/rpc/include/dpl/rpc/generic_socket_rpc_client.h b/modules/rpc/include/dpl/rpc/generic_socket_rpc_client.h new file mode 100644 index 0000000..9629e61 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/generic_socket_rpc_client.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket_rpc_client.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for generic socket RPC client + */ +#ifndef DPL_GENERIC_SOCKET_RPC_CLIENT_H +#define DPL_GENERIC_SOCKET_RPC_CLIENT_H + +#include +#include +#include + +namespace DPL { +namespace RPC { +template +class GenericSocketRPCClient : + public AbstractRPCConnector, + private DPL::Event::EventListener +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + + protected: + // Derived class implementations for connection managment + virtual AbstractRPCConnection *OpenSpecificConnection(SocketType *socket) = + 0; + + private: + typedef std::set InternalConnectionSet; + InternalConnectionSet m_internalConnectionSet; + + virtual void OnEventReceived( + const DPL::Socket::AbstractSocketEvents::ConnectedEvent &event) + { + // Retrieve socket sender + SocketType *socket = static_cast(event.GetSender()); + + LogPedantic("Connection with RPC server established"); + + // Is this connection still tracked ? + // It might have disappeared on close + typename InternalConnectionSet::iterator iterator = + m_internalConnectionSet.find(socket); + + if (iterator == m_internalConnectionSet.end()) { + LogPedantic("RPC client connection socket disappeared"); + return; + } + + // Open specific connection implementation + AbstractRPCConnection *connection = OpenSpecificConnection(socket); + + // Remove internal connection + socket->EventSupport + ::RemoveListener(this); + m_internalConnectionSet.erase(iterator); + + // Retrieve ID once again + AbstractRPCConnectionID connectionID = + static_cast(socket); + + // Inform listeners + DPL::Event::EventSupport:: + EmitEvent(AbstractRPCConnectorEvents::ConnectionEstablishedEvent( + connectionID, connection, EventSender( + this)), DPL::Event::EmitMode::Queued); + } + + public: + explicit GenericSocketRPCClient() + {} + + virtual ~GenericSocketRPCClient() + { + // Always close all connections + CloseAll(); + } + + AbstractRPCConnectionID Open(const Address &socketAddress) + { + LogPedantic("Starting client: " << socketAddress.ToString()); + + // Alloc new socket + SocketType *socket = new SocketType(); + + // Add socket listeners + socket->EventSupport + ::AddListener(this); + + Try + { + // Open socket + socket->Open(); + + // Start connecting to server + socket->Connect(Address(socketAddress)); + } + Catch(DPL::Socket::AbstractSocket::Exception::Base) + { + // Remove back socket listener + socket->EventSupport::RemoveListener(this); + + // Log debug message + LogPedantic("Cannot connect to: " << socketAddress.ToString()); + + // Problem with client startup + ReThrowMsg(typename Exception::OpenFailed, socketAddress.ToString()); + } + + // Register new internal connection + m_internalConnectionSet.insert(socket); + + // Debug info + LogPedantic( + "Client started on interface: " << + socket->GetLocalAddress().ToString()); + + // Return unique identifier + return static_cast(socket); + } + + void Close(AbstractRPCConnectionID connectionID) + { + LogPedantic("Closing client interface..."); + + // Get socket from ID + SocketType *socket = static_cast(connectionID); + + // Find corresponding internal connection + typename InternalConnectionSet::iterator iterator = + m_internalConnectionSet.find(socket); + + if (iterator == m_internalConnectionSet.end()) { + return; + } + + // Close socket + socket->Close(); + + // Remove internal socket + socket->EventSupport + ::RemoveListener(this); + delete socket; + + m_internalConnectionSet.erase(iterator); + + // Done + LogPedantic("Closed"); + } + + void CloseAll() + { + while (!m_internalConnectionSet.empty()) { + Close(static_cast(*m_internalConnectionSet + .begin())); + } + } +}; +} +} // namespace DPL + +#endif // DPL_GENERIC_SOCKET_RPC_CLIENT_H diff --git a/modules/rpc/include/dpl/rpc/generic_socket_rpc_connection.h b/modules/rpc/include/dpl/rpc/generic_socket_rpc_connection.h new file mode 100644 index 0000000..6c2d0ce --- /dev/null +++ b/modules/rpc/include/dpl/rpc/generic_socket_rpc_connection.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket_rpc_connection.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for generic socket RPC connection + */ +#ifndef DPL_GENERIC_SOCKET_RPC_CONNECTION_H +#define DPL_GENERIC_SOCKET_RPC_CONNECTION_H + +#include + +namespace DPL { +namespace RPC { +template +class GenericSocketRPCConnection : + public GenericRPCConnection +{ + protected: + // Private construction with socket acquisition + GenericSocketRPCConnection(SocketType *socket) : + GenericRPCConnection(socket) + {} +}; +} +} // namespace DPL + +#endif // DPL_GENERIC_SOCKET_RPC_CONNECTION_H diff --git a/modules/rpc/include/dpl/rpc/generic_socket_rpc_server.h b/modules/rpc/include/dpl/rpc/generic_socket_rpc_server.h new file mode 100644 index 0000000..a4cae00 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/generic_socket_rpc_server.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket_rpc_server.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for generic socket RPC server + */ +#ifndef DPL_GENERIC_SOCKET_RPC_SERVER_H +#define DPL_GENERIC_SOCKET_RPC_SERVER_H + +#include +#include +#include + +namespace DPL { +namespace RPC { +template +class GenericSocketRPCServer : + public AbstractRPCConnector, + private DPL::Event::EventListener +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + + protected: + // Derived class implementations for connection managment + virtual AbstractRPCConnection *OpenSpecificConnection(SocketType *socket) = + 0; + + private: + typedef std::set InternalInterfaceSet; + InternalInterfaceSet m_internalInterfacesSet; + + virtual void OnEventReceived( + const DPL::Socket::AbstractSocketEvents::AcceptEvent &event) + { + // Retrieve socket sender + SocketType *server = static_cast(event.GetSender()); + + // Is this interface still tracked ? + // It might have disappeared on close + typename InternalInterfaceSet::iterator iterator = + m_internalInterfacesSet.find(server); + + if (iterator == m_internalInterfacesSet.end()) { + LogPedantic("RPC server interface socket disappeared"); + return; + } + + // Accept incoming client + SocketType *client = static_cast(server->Accept()); + if (client == NULL) { + LogPedantic("Spontaneous accept on socket occurred"); + return; + } + + LogPedantic( + "Client connected to server: " << + client->GetRemoteAddress().ToString()); + + // Open specific connection implementation + AbstractRPCConnection *connection = OpenSpecificConnection(client); + + // Retrieve ID once again + AbstractRPCConnectionID connectionID = + static_cast(server); + + // Inform listeners + DPL::Event::EventSupport:: + EmitEvent(AbstractRPCConnectorEvents::ConnectionEstablishedEvent( + connectionID, connection, EventSender( + this)), DPL::Event::EmitMode::Queued); + } + + public: + explicit GenericSocketRPCServer() + {} + + virtual ~GenericSocketRPCServer() + { + // Always close connection + CloseAll(); + } + + AbstractRPCConnectionID Open(const Address &socketAddress) + { + LogPedantic("Starting server: " << socketAddress.ToString()); + + // Alloc new socket + SocketType *socket = new SocketType(); + + // Add socket listener + socket->EventSupport:: + AddListener(this); + + Try + { + // Open socket + socket->Open(); + + // Bind socket address + socket->Bind(socketAddress); + + // Start listening + socket->Listen(8); + } + Catch(DPL::Socket::AbstractSocket::Exception::Base) + { + // Remove back socket listener + socket->EventSupport + ::RemoveListener(this); + + // Log debug + LogPedantic("Cannot start server: " << socketAddress.ToString()); + + // Problem with server startup + ReThrowMsg(typename Exception::OpenFailed, socketAddress.ToString()); + } + + // Register new internal connection + m_internalInterfacesSet.insert(socket); + + // Debug info + LogPedantic( + "Server started on interface: " << + socket->GetLocalAddress().ToString()); + + // Return unique identifier + return static_cast(socket); + } + + void Close(AbstractRPCConnectionID connectionID) + { + LogPedantic("Closing server interface..."); + + // Get socket from ID + SocketType *socket = static_cast(connectionID); + + // Find corresponding internal connection + typename InternalInterfaceSet::iterator iterator = + m_internalInterfacesSet.find(socket); + + if (iterator == m_internalInterfacesSet.end()) { + return; + } + + // Close socket + socket->Close(); + + // Remove socket listeners + socket->EventSupport:: + RemoveListener(this); + delete socket; + + m_internalInterfacesSet.erase(iterator); + + // Done + LogPedantic("Closed"); + } + + void CloseAll() + { + while (!m_internalInterfacesSet.empty()) { + Close(static_cast(*m_internalInterfacesSet + .begin())); + } + } +}; +} +} // namespace DPL + +#endif // DPL_GENERIC_SOCKET_RPC_SERVER_H diff --git a/modules/rpc/include/dpl/rpc/rpc_function.h b/modules/rpc/include/dpl/rpc/rpc_function.h new file mode 100644 index 0000000..a01235f --- /dev/null +++ b/modules/rpc/include/dpl/rpc/rpc_function.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file rpc_function.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for RPC function + */ +#ifndef DPL_RPC_FUNCTION_H +#define DPL_RPC_FUNCTION_H + +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace RPC { +class RPCFunction : public IStream +{ + protected: + BinaryQueue m_buffer; ///< Serialized RPC function call as a binary queue + + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, ParseFailed) + }; + + /** + * Constructor + */ + RPCFunction() + {} + + /** + * Constructor + * + * @param buffer Binary queue to copy initialization data from + */ + RPCFunction(const BinaryQueue &buffer) + { + m_buffer.AppendCopyFrom(buffer); + } + + /** + * Destructor + */ + virtual ~RPCFunction() + {} + + /** + * Append argument to call + * + * @param[in] arg Template based argument to append + * @return none + * @warning Carefully add any pointers to buffer because of template nature + * of this method + */ + template + void AppendArg(const Type &arg) + { + size_t argSize = sizeof(arg); + m_buffer.AppendCopy(&argSize, sizeof(argSize)); + m_buffer.AppendCopy(&arg, sizeof(arg)); + } + + /** + * Append @a std::string argument to call + * + * @param[in] arg String to append to function call + * @return none + */ + void AppendArg(const std::string &arg) + { + size_t argSize = arg.size(); + m_buffer.AppendCopy(&argSize, sizeof(argSize)); + m_buffer.AppendCopy(arg.c_str(), argSize); + } + + /** + * Append @a DPL::String argument to call + * + * @param[in] arg String to append to function call + * @return none + */ + void AppendArg(const String &arg) + { + std::string localStdString = ToUTF8String(arg); + AppendArg(localStdString); + } + + /** + * Consume argument from call. Arguments are retrieved in non-reversed order + * (same as they were pushed onto RPC function argument stack) + * + * @param[out] arg Reference to output template based argument + * @warning Carefully add any pointers to buffer because of template nature + * of this method + * @return none + */ + template + void ConsumeArg(Type &arg) + { + Try + { + size_t argSize = sizeof(arg); + m_buffer.FlattenConsume(&argSize, sizeof(argSize)); + + if (argSize != sizeof(arg)) { + ThrowMsg(Exception::ParseFailed, "Stream parse CRC failed"); + } + + m_buffer.FlattenConsume(&arg, sizeof(arg)); + } + Catch(BinaryQueue::Exception::OutOfData) + { + ReThrowMsg(Exception::ParseFailed, "Unexpected end of stream"); + } + } + + /** + * Consume @a std::string argument from call. Arguments are retrieved in + * non-reversed order + * (same as they were pushed onto RPC function argument stack) + * + * @param[out] arg Reference to output @a std::string argument + * @return none + */ + void ConsumeArg(std::string &arg) + { + Try + { + std::string::size_type size; + m_buffer.FlattenConsume(&size, sizeof(size)); + ScopedArray str(new char[size]); + m_buffer.FlattenConsume(str.Get(), size); + arg = std::string(str.Get(), str.Get() + size); + } + Catch(BinaryQueue::Exception::OutOfData) + { + ReThrowMsg(Exception::ParseFailed, "Unexpected end of stream"); + } + } + + /** + * Consume @a DPL::String argument from call. Arguments are converted to + * UTF-8 string + * + * @param[out] arg Reference to output @a DPL::String argument + * @return none + */ + void ConsumeArg(String &arg) + { + std::string consumedStdString; + ConsumeArg(consumedStdString); + arg = FromUTF8String(consumedStdString); + } + + /** + * Serialize all function parameters into single binary queue + * + * @return Serialized binary queue representation of RPC function + */ + BinaryQueue Serialize() const + { + return m_buffer; + } + + /** + * Reads binary data from serialized stream + * + * @param num number of bytes to read + * @param bytes buffer for read data + */ + virtual void Read(size_t num, void * bytes) + { + m_buffer.FlattenConsume(bytes, num); + } + + /** + * Writes binary data to serialized stream + * + * @param num number of bytes to write to serialization buffer + * @param bytes buffer for data to write + */ + virtual void Write(size_t num, const void * bytes) + { + m_buffer.AppendCopy(bytes, num); + } +}; +} +} // namespace DPL + +#endif // DPL_RPC_FUNCTION_H diff --git a/modules/rpc/include/dpl/rpc/unix_socket_rpc_client.h b/modules/rpc/include/dpl/rpc/unix_socket_rpc_client.h new file mode 100644 index 0000000..aba62ec --- /dev/null +++ b/modules/rpc/include/dpl/rpc/unix_socket_rpc_client.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_client.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for unix socket RPC client + */ +#ifndef DPL_UNIX_SOCKET_RPC_CLIENT_H +#define DPL_UNIX_SOCKET_RPC_CLIENT_H + +#include +#include +#include + +namespace DPL { +namespace RPC { +class UnixSocketRPCClient : + public GenericSocketRPCClient +{ + protected: + virtual AbstractRPCConnection *OpenSpecificConnection( + DPL::Socket::UnixSocket *socket); + + public: + AbstractRPCConnectionID Open(const std::string &fileName); +}; +} +} // namespace DPL + +#endif // DPL_UNIX_SOCKET_RPC_CLIENT_H diff --git a/modules/rpc/include/dpl/rpc/unix_socket_rpc_connection.h b/modules/rpc/include/dpl/rpc/unix_socket_rpc_connection.h new file mode 100644 index 0000000..9b00141 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/unix_socket_rpc_connection.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_connection.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for unix socket RPC connection + */ +#ifndef DPL_UNIX_SOCKET_RPC_CONNECTION_H +#define DPL_UNIX_SOCKET_RPC_CONNECTION_H + +#include +#include + +namespace DPL { +namespace RPC { +class UnixSocketRPCConnection : + public GenericSocketRPCConnection +{ + public: + // Socket acquisition + UnixSocketRPCConnection(DPL::Socket::UnixSocket *socket); +}; +} +} // namespace DPL + +#endif // DPL_UNIX_SOCKET_RPC_CONNECTION_H diff --git a/modules/rpc/include/dpl/rpc/unix_socket_rpc_server.h b/modules/rpc/include/dpl/rpc/unix_socket_rpc_server.h new file mode 100644 index 0000000..de2b605 --- /dev/null +++ b/modules/rpc/include/dpl/rpc/unix_socket_rpc_server.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_server.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for unix socket RPC server + */ +#ifndef DPL_UNIX_SOCKET_RPC_SERVER_H +#define DPL_UNIX_SOCKET_RPC_SERVER_H + +#include +#include +#include + +namespace DPL { +namespace RPC { +class UnixSocketRPCServer : + public GenericSocketRPCServer +{ + protected: + virtual AbstractRPCConnection *OpenSpecificConnection( + DPL::Socket::UnixSocket *socket); + + public: + AbstractRPCConnectionID Open(const std::string &fileName); +}; +} +} // namespace DPL + +#endif // DPL_UNIX_SOCKET_RPC_SERVER_H diff --git a/modules/rpc/src/abstract_rpc_connection.cpp b/modules/rpc/src/abstract_rpc_connection.cpp new file mode 100644 index 0000000..e5455e2 --- /dev/null +++ b/modules/rpc/src/abstract_rpc_connection.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_rpc_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract RPC connection + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/rpc/src/abstract_rpc_connector.cpp b/modules/rpc/src/abstract_rpc_connector.cpp new file mode 100644 index 0000000..2bd879e --- /dev/null +++ b/modules/rpc/src/abstract_rpc_connector.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_rpc_connector.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract RPC connector + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/rpc/src/generic_rpc_connection.cpp b/modules/rpc/src/generic_rpc_connection.cpp new file mode 100644 index 0000000..6b16f28 --- /dev/null +++ b/modules/rpc/src/generic_rpc_connection.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_rpc_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of generic RPC connection + */ +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace RPC { +namespace // anonymous +{ +namespace Protocol { +// Packet definitions +enum PacketType +{ + PacketType_AsyncCall, + PacketType_PingPong +}; + +struct Header +{ + unsigned short size; + unsigned short type; +} DPL_ALIGNED(1); + +struct AsyncCall : + public Header +{ + unsigned char data[1]; +} DPL_ALIGNED(1); +} // namespace Protocol +} // namespace anonymous + +GenericRPCConnection::GenericRPCConnection( + AbstractWaitableInputOutput *inputOutput) : + m_inputOutput(inputOutput) +{ + LogPedantic("Opening generic RPC..."); + WaitableInputOutputExecutionContextSupport::Open(inputOutput); + LogPedantic("Generic RPC opened"); +} + +GenericRPCConnection::~GenericRPCConnection() +{ + // Ensure RPC is closed + LogPedantic("Closing generic RPC..."); + WaitableInputOutputExecutionContextSupport::Close(); + LogPedantic("Generic RPC closed"); +} + +void GenericRPCConnection::AsyncCall(const RPCFunction &function) +{ + LogPedantic("Executing async call"); + + // Create binary call + BinaryQueue serializedCall = function.Serialize(); + + // Append buffers + Protocol::AsyncCall call; + call.size = static_cast(serializedCall.Size()); + call.type = Protocol::PacketType_AsyncCall; + + m_outputStream.AppendCopy(&call, sizeof(Protocol::Header)); + m_outputStream.AppendMoveFrom(serializedCall); + + // Try to feed output with data + Try + { + FeedOutput(); + } + Catch(WaitableInputOutputExecutionContextSupport::Exception::NotOpened) + { + // Error occurred while feeding + ReThrow(AbstractRPCConnection::Exception::AsyncCallFailed); + } +} + +void GenericRPCConnection::Ping() +{ + LogPedantic("Executing ping call"); + + // Append buffers + Protocol::AsyncCall call; + call.size = 0; + call.type = Protocol::PacketType_PingPong; + + m_outputStream.AppendCopy(&call, sizeof(Protocol::Header)); + + // Try to feed output with data + Try + { + FeedOutput(); + } + Catch(WaitableInputOutputExecutionContextSupport::Exception::NotOpened) + { + // Error occurred while feeding + ReThrow(AbstractRPCConnection::Exception::PingFailed); + } +} + +void GenericRPCConnection::OnInputStreamRead() +{ + LogPedantic("Interpreting " << m_inputStream.Size() << " bytes buffer"); + + // Enough bytes to read at least one header ? + if (m_inputStream.Size() >= sizeof(Protocol::Header)) { + // Begin consuming as much packets as it is possible + while (m_inputStream.Size() >= sizeof(Protocol::Header)) { + Protocol::Header header; + m_inputStream.Flatten(&header, sizeof(header)); + + if (m_inputStream.Size() >= sizeof(Protocol::Header) + + header.size) + { + LogPedantic("Will parse packet of type: " << header.type); + + // Allocate new packet (header + real packet data) + void *binaryPacket = malloc( + sizeof(Protocol::Header) + header.size); + + if (binaryPacket == NULL) { + throw std::bad_alloc(); + } + + // Get it from stream + m_inputStream.FlattenConsume( + binaryPacket, + sizeof(Protocol::Header) + + header.size); + + // Parse specific packet + switch (header.type) { + case Protocol::PacketType_AsyncCall: + { + BinaryQueue call; + + // No need to delete packet data, we can use it + call.AppendUnmanaged(binaryPacket, + sizeof(Protocol::Header) + header.size, + &BinaryQueue::BufferDeleterFree, + NULL); + + // ...but just remove protocol header + call.Consume(sizeof(Protocol::Header)); + + LogPedantic( + "Async call of size: " << header.size << + " parsed"); + + // Call async call event listeners + DPL::Event::EventSupport:: + EmitEvent(AbstractRPCConnectionEvents::AsyncCallEvent( + RPCFunction(call), EventSender( + this)), DPL::Event::EmitMode::Queued); + } + break; + + case Protocol::PacketType_PingPong: + { + // Reply with ping/pong + Ping(); + + // Do not need packet data + free(binaryPacket); + + LogPedantic("Ping pong replied"); + } + break; + + default: + LogPedantic("Warning: Unknown packet type"); + free(binaryPacket); + break; + } + } else { + LogPedantic("Too few bytes to read packet"); + break; + } + } + } else { + LogPedantic("Too few bytes to read header"); + } +} + +void GenericRPCConnection::OnInputStreamClosed() +{ + // Emit closed event + DPL::Event::EventSupport + :: + EmitEvent(AbstractRPCConnectionEvents::ConnectionClosedEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); +} + +void GenericRPCConnection::OnInputStreamBroken() +{ + // Emit broken event + DPL::Event::EventSupport + :: + EmitEvent(AbstractRPCConnectionEvents::ConnectionBrokenEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); +} +} +} // namespace DPL diff --git a/modules/rpc/src/generic_socket_rpc_client.cpp b/modules/rpc/src/generic_socket_rpc_client.cpp new file mode 100644 index 0000000..51c1b97 --- /dev/null +++ b/modules/rpc/src/generic_socket_rpc_client.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket_rpc_client.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of generic socket RPC + * client + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/rpc/src/generic_socket_rpc_connection.cpp b/modules/rpc/src/generic_socket_rpc_connection.cpp new file mode 100644 index 0000000..2d84a4a --- /dev/null +++ b/modules/rpc/src/generic_socket_rpc_connection.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket_rpc_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of generic socket RPC + * connection + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/rpc/src/generic_socket_rpc_server.cpp b/modules/rpc/src/generic_socket_rpc_server.cpp new file mode 100644 index 0000000..a0590f4 --- /dev/null +++ b/modules/rpc/src/generic_socket_rpc_server.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket_rpc.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of generic socket RPC + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/rpc/src/unix_socket_rpc_client.cpp b/modules/rpc/src/unix_socket_rpc_client.cpp new file mode 100644 index 0000000..8b105f2 --- /dev/null +++ b/modules/rpc/src/unix_socket_rpc_client.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_client.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of unix socket RPC client + */ +#include +#include +#include + +namespace DPL { +namespace RPC { +AbstractRPCConnection *UnixSocketRPCClient::OpenSpecificConnection( + DPL::Socket::UnixSocket *socket) +{ + // Allocate new UNIX/RPC connection object + UnixSocketRPCConnection *connection = new UnixSocketRPCConnection(socket); + + // Return new connection + return connection; +} + +AbstractRPCConnectionID UnixSocketRPCClient::Open(const std::string &fileName) +{ + return GenericSocketRPCClient::Open(Address( + fileName)); +} +} +} // namespace DPL diff --git a/modules/rpc/src/unix_socket_rpc_connection.cpp b/modules/rpc/src/unix_socket_rpc_connection.cpp new file mode 100644 index 0000000..b21098d --- /dev/null +++ b/modules/rpc/src/unix_socket_rpc_connection.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of unix socket RPC + * connection + */ +#include +#include + +namespace DPL { +namespace RPC { +UnixSocketRPCConnection::UnixSocketRPCConnection( + DPL::Socket::UnixSocket *socket) : + GenericSocketRPCConnection(socket) +{} +} +} // namespace DPL diff --git a/modules/rpc/src/unix_socket_rpc_server.cpp b/modules/rpc/src/unix_socket_rpc_server.cpp new file mode 100644 index 0000000..e9dd9ab --- /dev/null +++ b/modules/rpc/src/unix_socket_rpc_server.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket_rpc_server.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of unix socket RPC server + */ +#include +#include +#include + +namespace DPL { +namespace RPC { +AbstractRPCConnection *UnixSocketRPCServer::OpenSpecificConnection( + DPL::Socket::UnixSocket *socket) +{ + // Allocate new UNIX/RPC connection object + UnixSocketRPCConnection *connection = new UnixSocketRPCConnection(socket); + + // Return new connection + return connection; +} + +AbstractRPCConnectionID UnixSocketRPCServer::Open(const std::string &fileName) +{ + return GenericSocketRPCServer::Open(Address( + fileName)); +} +} +} // namespace DPL diff --git a/modules/security_origin_dao/CMakeLists.txt b/modules/security_origin_dao/CMakeLists.txt new file mode 100644 index 0000000..f307a2b --- /dev/null +++ b/modules/security_origin_dao/CMakeLists.txt @@ -0,0 +1,55 @@ +SET(TARGET_SECURITY_ORIGIN_DAO_DB "Sqlite3DbSecurityOrigin") + +ADD_CUSTOM_COMMAND( OUTPUT .security_origin.db + COMMAND rm -f ${CMAKE_CURRENT_BINARY_DIR}/.security_origin.db + COMMAND gcc -Wall -I${PROJECT_SOURCE_DIR}/modules/db/include -I${PROJECT_SOURCE_DIR}/modules/security_origin_dao/orm -E ${PROJECT_SOURCE_DIR}/modules/security_origin_dao/orm/security_origin_db_sql_generator.h | grep --invert-match "^#" > ${CMAKE_CURRENT_BINARY_DIR}/security_origin_db.sql + COMMAND sqlite3 ${CMAKE_CURRENT_BINARY_DIR}/.security_origin.db ".read ${CMAKE_CURRENT_BINARY_DIR}/security_origin_db.sql" || rm -f ${CMAKE_CURRENT_BINARY_DIR}/.security_origin.db + DEPENDS ${PROJECT_SOURCE_DIR}/modules/security_origin_dao/orm/security_origin_db_sql_generator.h ${PROJECT_SOURCE_DIR}/modules/security_origin_dao/orm/security_origin_db + ) + +ADD_CUSTOM_COMMAND( OUTPUT .security_origin.db-journal + COMMAND touch + ARGS ${CMAKE_CURRENT_BINARY_DIR}/.security_origin.db-journal + ) + +ADD_CUSTOM_TARGET(${TARGET_SECURITY_ORIGIN_DAO_DB} ALL DEPENDS .security_origin.db .security_origin.db-journal) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/security_origin_db.sql DESTINATION share/wrt-engine/) + +############################################################################### + +INCLUDE(FindPkgConfig) + +PKG_CHECK_MODULES(SECURITY_ORIGIN_DAO_DEPS + glib-2.0 + REQUIRED) + +SET(SECURITY_ORIGIN_DAO_INCLUDE_DIRS + ${PROJECT_SOURCE_DIR}/modules/security_origin_dao/include + ${PROJECT_SOURCE_DIR}/modules/security_origin_dao/orm + ${PROJECT_SOURCE_DIR}/modules/core/include + ${PROJECT_SOURCE_DIR}/modules/db/include + ${PROJECT_SOURCE_DIR}/modules/log/include + ${PROJECT_SOURCE_DIR}/modules/widget_dao/include +) + +SET(SECURITY_ORIGIN_DAO_SOURCES + dao/security_origin_dao_types.cpp + dao/security_origin_dao.cpp +) + +INCLUDE_DIRECTORIES(SYSTEM ${SECURITY_ORIGIN_DAO_DEPS_INCLUDE_DIRS} ) +INCLUDE_DIRECTORIES(${SECURITY_ORIGIN_DAO_INCLUDE_DIRS}) + +ADD_LIBRARY(${TARGET_SECURITY_ORIGIN_DAO_LIB} SHARED ${SECURITY_ORIGIN_DAO_SOURCES}) +SET_TARGET_PROPERTIES(${TARGET_SECURITY_ORIGIN_DAO_LIB} PROPERTIES SOVERSION ${API_VERSION} VERSION ${VERSION}) +TARGET_LINK_LIBRARIES(${TARGET_SECURITY_ORIGIN_DAO_LIB} ${TARGET_DPL_EFL} ${TARGET_DPL_DB_EFL} ${TARGET_WRT_DAO_RO_LIB} ${SECURITY_ORIGIN_DAO_DEPS_LIBRARIES}) +ADD_DEPENDENCIES(${TARGET_SECURITY_ORIGIN_DAO_LIB} ${TARGET_SECURITY_ORIGIN_DAO_DB}) + +INSTALL(TARGETS ${TARGET_SECURITY_ORIGIN_DAO_LIB} DESTINATION lib) + +INSTALL(FILES + include/wrt-commons/security-origin-dao/security_origin_dao_types.h + include/wrt-commons/security-origin-dao/security_origin_dao.h + DESTINATION include/dpl-efl/wrt-commons/security-origin-dao +) + diff --git a/modules/security_origin_dao/dao/security_origin_dao.cpp b/modules/security_origin_dao/dao/security_origin_dao.cpp new file mode 100644 index 0000000..7551189 --- /dev/null +++ b/modules/security_origin_dao/dao/security_origin_dao.cpp @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file security_origin_dao.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + * @brief This file contains the definition of security origin dao class. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace DPL::DB::ORM; +using namespace DPL::DB::ORM::security_origin; + +namespace SecurityOriginDB { +using namespace WrtDB; +#define SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN Try + +#define SQL_CONNECTION_EXCEPTION_HANDLER_END(message) \ + Catch(DPL::DB::SqlConnection::Exception::Base) { \ + LogError(message); \ + ReThrowMsg(SecurityOriginDAO::Exception::DatabaseError, \ + message); \ + } + +// database connection +#define SECURITY_ORIGIN_DB_INTERNAL(tlsCommand, InternalType, interface) \ + InternalType tlsCommand(interface); +#define SECURITY_ORIGIN_DB_SELECT(name, type, interface) \ + SECURITY_ORIGIN_DB_INTERNAL(name, type::Select, interface) +#define SECURITY_ORIGIN_DB_INSERT(name, type, interface) \ + SECURITY_ORIGIN_DB_INTERNAL(name, type::Insert, interface) +#define SECURITY_ORIGIN_DB_UPDATE(name, type, interface) \ + SECURITY_ORIGIN_DB_INTERNAL(name, type::Update, interface) +#define SECURITY_ORIGIN_DB_DELETE(name, type, interface) \ + SECURITY_ORIGIN_DB_INTERNAL(name, type::Delete, interface) + +typedef DPL::DB::ORM::security_origin::SecurityOriginInfo::Row + SecurityOriginInfoRow; +typedef DPL::DB::ORM::security_origin::SecurityOriginInfo::Select::RowList + SecurityOriginInfoRowList; + +namespace { +DPL::DB::SqlConnection::Flag::Option SECURITY_ORIGIN_DB_OPTION = + DPL::DB::SqlConnection::Flag::RW; +DPL::DB::SqlConnection::Flag::Type SECURITY_ORIGIN_DB_TYPE = + DPL::DB::SqlConnection::Flag::UseLucene; +const char* const SECURITY_ORIGIN_DB_NAME = ".security_origin.db"; +const char* const SECURITY_ORIGIN_DB_SQL_PATH = + "/usr/share/wrt-engine/security_origin_db.sql"; +const char* const SECURITY_DATABASE_JOURNAL_FILENAME = "-journal"; + +const int WEB_APPLICATION_UID = 5000; +const int WEB_APPLICATION_GUID = 5000; + +std::string createDatabasePath(const WrtDB::TizenPkgId &pkgName) +{ + std::stringstream filename; + + filename << WrtDB::WidgetConfig::GetWidgetPersistentStoragePath(pkgName) + << "/" + << SECURITY_ORIGIN_DB_NAME; + return filename.str(); +} + +void checkDatabase(std::string databasePath) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + if (databasePath.empty()) { + ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, + "Wrong database Path is passed"); + } + + struct stat buffer; + if (stat(databasePath.c_str(), &buffer) != 0) { + //Create fresh database + LogDebug("Creating database " << databasePath); + + std::fstream file; + file.open(SECURITY_ORIGIN_DB_SQL_PATH, std::ios_base::in); + if (!file) { + ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, + "Fail to get database Path"); + } + + std::stringstream ssBuffer; + ssBuffer << file.rdbuf(); + + file.close(); + + DPL::DB::SqlConnection con(databasePath, + SECURITY_ORIGIN_DB_TYPE, + SECURITY_ORIGIN_DB_OPTION); + con.ExecCommand(ssBuffer.str().c_str()); + + if(chown(databasePath.c_str(), + WEB_APPLICATION_UID, + WEB_APPLICATION_GUID) != 0) + { + ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, + "Fail to change uid/guid"); + } + std::string databaseJournal = + databasePath + SECURITY_DATABASE_JOURNAL_FILENAME; + if(chown(databaseJournal.c_str(), + WEB_APPLICATION_UID, + WEB_APPLICATION_GUID) != 0) + { + ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, + "Fail to change uid/guid"); + } + } + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to get database Path") +} +} // namespace SecurityOriginDB + +SecurityOriginDAO::SecurityOriginDAO(const WrtDB::TizenPkgId &pkgName) : + m_dbPath(createDatabasePath(pkgName)), + m_dbInterface(m_dbPath, SECURITY_ORIGIN_DB_TYPE) +{ + checkDatabase(m_dbPath); + m_dbInterface.AttachToThread(SECURITY_ORIGIN_DB_OPTION); +} + +SecurityOriginDAO::~SecurityOriginDAO() +{ + m_dbInterface.DetachFromThread(); +} + +SecurityOriginDataList SecurityOriginDAO::getSecurityOriginDataList(void) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + SecurityOriginDataList list; + SECURITY_ORIGIN_DB_SELECT(select, SecurityOriginInfo, &m_dbInterface); + typedef std::list RowList; + RowList rowList = select.GetRowList(); + + FOREACH(it, rowList) { + Origin origin(it->Get_scheme(), it->Get_host(), it->Get_port()); + list.push_back( + SecurityOriginDataPtr( + new SecurityOriginData( + static_cast(it->Get_feature()), origin))); + } + return list; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get data list") +} + +Result SecurityOriginDAO::getResult(const SecurityOriginData &data) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + SECURITY_ORIGIN_DB_SELECT(select, SecurityOriginInfo, &m_dbInterface); + Equals eFeature(data.feature); + Equals eScheme(data.origin.scheme); + Equals eHost(data.origin.host); + Equals ePort(data.origin.port); + select.Where(And(And(And(eFeature, eScheme), eHost), ePort)); + SecurityOriginInfoRowList rows = select.GetRowList(); + if (rows.empty()) { + return RESULT_UNKNOWN; + } + SecurityOriginInfoRow row = rows.front(); + return static_cast(row.Get_result()); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("getResult error") +} + +bool SecurityOriginDAO::isReadOnly(const SecurityOriginData &data) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + SECURITY_ORIGIN_DB_SELECT(select, SecurityOriginInfo, &m_dbInterface); + Equals eFeature(data.feature); + Equals eScheme(data.origin.scheme); + Equals eHost(data.origin.host); + Equals ePort(data.origin.port); + select.Where(And(And(And(eFeature, eScheme), eHost), ePort)); + SecurityOriginInfoRowList rows = select.GetRowList(); + if (rows.empty()) { + return RESULT_UNKNOWN; + } + SecurityOriginInfoRow row = rows.front(); + return row.Get_readonly() ? true : false; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("isReadOnly error") +} + +void SecurityOriginDAO::setSecurityOriginData(const SecurityOriginData &data, + const Result result, + const bool readOnly) +{ + if (true == hasResult(data)) { + updateData(data, result, readOnly); + } else { + insertData(data, result, readOnly); + } +} + +void SecurityOriginDAO::setPrivilegeSecurityOriginData( + const Feature feature, + bool isOnlyAllowedLocalOrigin) +{ + //TODO: this breaks app:// scheme code -> no case for app scheme + Origin origin(DPL::FromUTF8String("file"), + DPL::FromUTF8String(""), + 0); + if (!isOnlyAllowedLocalOrigin) { + origin.scheme = DPL::FromUTF8String(""); + } + SecurityOriginData data(feature, origin); + setSecurityOriginData(data, RESULT_ALLOW_ALWAYS, true); +} + +void SecurityOriginDAO::removeSecurityOriginData( + const SecurityOriginData &data) +{ + if (false == hasResult(data)) { + // There is no data + return; + } + + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + ScopedTransaction transaction(&m_dbInterface); + SECURITY_ORIGIN_DB_DELETE(del, SecurityOriginInfo, &m_dbInterface) + Equals eFeature(data.feature); + Equals eScheme(data.origin.scheme); + Equals eHost(data.origin.host); + Equals ePort(data.origin.port); + del.Where(And(And(And(eFeature, eScheme), eHost), ePort)); + del.Execute(); + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to remove security origin data") +} + +void SecurityOriginDAO::removeSecurityOriginData(const Result result) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + ScopedTransaction transaction(&m_dbInterface); + SECURITY_ORIGIN_DB_DELETE(del, SecurityOriginInfo, &m_dbInterface) + del.Where(Equals(result)); + del.Execute(); + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to remove data by result") +} + +bool SecurityOriginDAO::hasResult(const SecurityOriginData &data) +{ + Result ret = getResult(data); + return (ret != RESULT_UNKNOWN); +} + +void SecurityOriginDAO::insertData(const SecurityOriginData &data, + const Result result, + const bool readOnly) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + SecurityOriginInfoRow row; + row.Set_feature(data.feature); + row.Set_scheme(data.origin.scheme); + row.Set_host(data.origin.host); + row.Set_port(data.origin.port); + row.Set_result(result); + row.Set_readonly(readOnly ? 1 : 0); + + ScopedTransaction transaction(&m_dbInterface); + SECURITY_ORIGIN_DB_INSERT(insert, SecurityOriginInfo, &m_dbInterface); + insert.Values(row); + insert.Execute(); + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to insert") +} + +void SecurityOriginDAO::updateData(const SecurityOriginData &data, + const Result result, + const bool readOnly) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + SecurityOriginInfoRow row; + row.Set_feature(data.feature); + row.Set_scheme(data.origin.scheme); + row.Set_host(data.origin.host); + row.Set_port(data.origin.port); + row.Set_result(result); + row.Set_readonly(readOnly ? 1 : 0); + + ScopedTransaction transaction(&m_dbInterface); + SECURITY_ORIGIN_DB_UPDATE(update, SecurityOriginInfo, &m_dbInterface); + Equals eFeature(data.feature); + Equals eScheme(data.origin.scheme); + Equals eHost(data.origin.host); + Equals ePort(data.origin.port); + update.Where(And(And(And(eFeature, eScheme), eHost), ePort)); + update.Values(row); + update.Execute(); + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to update") +} +#undef SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN +#undef SQL_CONNECTION_EXCEPTION_HANDLER_END +} // namespace SecurityOriginDB diff --git a/modules/security_origin_dao/dao/security_origin_dao_types.cpp b/modules/security_origin_dao/dao/security_origin_dao_types.cpp new file mode 100755 index 0000000..8d2a9f8 --- /dev/null +++ b/modules/security_origin_dao/dao/security_origin_dao_types.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file security_origin_dao_types.cpp + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + * @brief This file contains the implementation of + * common data types for wrt_security_origin.db + */ + +#include +#include + +namespace SecurityOriginDB { +} // namespace SecurityOriginDB diff --git a/modules/security_origin_dao/include/wrt-commons/security-origin-dao/security_origin_dao.h b/modules/security_origin_dao/include/wrt-commons/security-origin-dao/security_origin_dao.h new file mode 100644 index 0000000..d922764 --- /dev/null +++ b/modules/security_origin_dao/include/wrt-commons/security-origin-dao/security_origin_dao.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file securoty_origin_dao.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of security origin dao + */ +#ifndef _SECURITY_ORIGIN_DAO_H_ +#define _SECURITY_ORIGIN_DAO_H_ + +#include +#include +#include +#include + +namespace SecurityOriginDB { +class SecurityOriginDAO +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DatabaseError) + DECLARE_EXCEPTION_TYPE(Base, DataNotExist) + }; + + explicit SecurityOriginDAO(const WrtDB::TizenPkgId &pkgName); + virtual ~SecurityOriginDAO(); + SecurityOriginDataList getSecurityOriginDataList(); + Result getResult(const SecurityOriginData &data); + bool isReadOnly(const SecurityOriginData &data); + void setSecurityOriginData(const SecurityOriginData &data, + const Result result, + const bool readOnly = false); + void setPrivilegeSecurityOriginData(const WrtDB::Feature feature, + bool isOnlyAllowedLocalOrigin = true); + void removeSecurityOriginData(const SecurityOriginData &data); + void removeSecurityOriginData(const Result result); + + private: + std::string m_dbPath; + DPL::DB::ThreadDatabaseSupport m_dbInterface; + + bool hasResult(const SecurityOriginData &data); + void insertData(const SecurityOriginData &data, + const Result result, + const bool readOnly); + void updateData(const SecurityOriginData &data, + const Result result, + const bool readOnly); +}; + +typedef std::shared_ptr SecurityOriginDAOPtr; +} // namespace SecurityOriginDB + +#endif // _SECURITY_ORIGIN_DAO_H_ diff --git a/modules/security_origin_dao/include/wrt-commons/security-origin-dao/security_origin_dao_types.h b/modules/security_origin_dao/include/wrt-commons/security-origin-dao/security_origin_dao_types.h new file mode 100755 index 0000000..4753925 --- /dev/null +++ b/modules/security_origin_dao/include/wrt-commons/security-origin-dao/security_origin_dao_types.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file security_origin_dao_types.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of + * common data types for security origin database. + */ +#ifndef _SECURITY_ORIGIN_DAO_TYPES_H_ +#define _SECURITY_ORIGIN_DAO_TYPES_H_ + +#include +#include +#include +#include +#include + +namespace SecurityOriginDB { +enum Result +{ + RESULT_UNKNOWN = 0, + RESULT_ALLOW_ONCE, + RESULT_DENY_ONCE, + RESULT_ALLOW_ALWAYS, + RESULT_DENY_ALWAYS +}; + +struct Origin +{ + DPL::String scheme; + DPL::String host; + unsigned int port; + + Origin(const DPL::String& Scheme, + const DPL::String& Host, + const unsigned int Port) : + scheme(Scheme), + host(Host), + port(Port) + {} + + bool operator== (const Origin& other) const + { + return (!DPL::StringCompare(scheme, other.scheme) && + !DPL::StringCompare(host, other.host) && + port == other.port); + } + + bool operator!= (const Origin& other) const + { + return !(*this == other); + } +}; + +struct SecurityOriginData +{ + WrtDB::Feature feature; + Origin origin; + + SecurityOriginData(const WrtDB::Feature features, const Origin& ori) : + feature(features), + origin(ori) + {} + + bool operator== (const SecurityOriginData& other) const + { + return (origin == other.origin) && + (feature == other.feature); + } + + bool operator!= (const SecurityOriginData& other) const + { + return !(*this == other); + } +}; + +typedef std::shared_ptr SecurityOriginDataPtr; +typedef std::list SecurityOriginDataList; +} // namespace SecurityOriginDB + +#endif // _SECURITY_ORIGIN_DAO_TYPES_H_ diff --git a/modules/security_origin_dao/orm/orm_generator_security_origin.h b/modules/security_origin_dao/orm/orm_generator_security_origin.h new file mode 100644 index 0000000..84888de --- /dev/null +++ b/modules/security_origin_dao/orm/orm_generator_security_origin.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ORM_GENERATOR_SECURITY_ORIGIN_H_ +#define _ORM_GENERATOR_SECURITY_ORIGIN_H_ + +#define ORM_GENERATOR_DATABASE_NAME security_origin_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif // _ORM_GENERATOR_SECURITY_ORIGIN_H_ diff --git a/modules/security_origin_dao/orm/security_origin_db b/modules/security_origin_dao/orm/security_origin_db new file mode 100644 index 0000000..2d9c4f9 --- /dev/null +++ b/modules/security_origin_dao/orm/security_origin_db @@ -0,0 +1,13 @@ +SQL(BEGIN TRANSACTION;) + +CREATE_TABLE(SecurityOriginInfo) + COLUMN_NOT_NULL(feature, INT, ) + COLUMN_NOT_NULL(scheme, TEXT,DEFAULT '') + COLUMN_NOT_NULL(host, TEXT,DEFAULT '') + COLUMN_NOT_NULL(port, INT, DEFAULT 0) + COLUMN_NOT_NULL(result, INT, DEFAULT 0) + COLUMN_NOT_NULL(readonly, INT, DEFAULT 0) + TABLE_CONSTRAINTS(PRIMARY KEY(feature,scheme,host,port)) +CREATE_TABLE_END() + +SQL(COMMIT;) diff --git a/modules/security_origin_dao/orm/security_origin_db_definitions b/modules/security_origin_dao/orm/security_origin_db_definitions new file mode 100644 index 0000000..dc74f98 --- /dev/null +++ b/modules/security_origin_dao/orm/security_origin_db_definitions @@ -0,0 +1,5 @@ +DATABASE_START(security_origin) + +#include "security_origin_db" + +DATABASE_END() diff --git a/modules/security_origin_dao/orm/security_origin_db_sql_generator.h b/modules/security_origin_dao/orm/security_origin_db_sql_generator.h new file mode 100644 index 0000000..3bdbe6d --- /dev/null +++ b/modules/security_origin_dao/orm/security_origin_db_sql_generator.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file security_origin_db_sql_generator.h + * @author Jihoon Chung (jihoon.chung@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL + * input file from database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. +#include + +#include "security_origin_db_definitions" diff --git a/modules/socket/config.cmake b/modules/socket/config.cmake new file mode 100644 index 0000000..6e097a4 --- /dev/null +++ b/modules/socket/config.cmake @@ -0,0 +1,40 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_SOCKET_SOURCES + ${PROJECT_SOURCE_DIR}/modules/socket/src/generic_socket.cpp + ${PROJECT_SOURCE_DIR}/modules/socket/src/unix_socket.cpp + ${PROJECT_SOURCE_DIR}/modules/socket/src/waitable_input_output_execution_context_support.cpp + PARENT_SCOPE +) + +SET(DPL_SOCKET_HEADERS + ${PROJECT_SOURCE_DIR}/modules/socket/include/dpl/socket/abstract_socket.h + ${PROJECT_SOURCE_DIR}/modules/socket/include/dpl/socket/generic_socket.h + ${PROJECT_SOURCE_DIR}/modules/socket/include/dpl/socket/unix_socket.h + ${PROJECT_SOURCE_DIR}/modules/socket/include/dpl/socket/waitable_input_output_execution_context_support.h + PARENT_SCOPE +) + +SET(DPL_SOCKET_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/socket/include/ + PARENT_SCOPE +) diff --git a/modules/socket/include/dpl/socket/abstract_socket.h b/modules/socket/include/dpl/socket/abstract_socket.h new file mode 100644 index 0000000..0c06f99 --- /dev/null +++ b/modules/socket/include/dpl/socket/abstract_socket.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_socket.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of abstract socket + */ +#ifndef DPL_ABSTRACT_SOCKET_H +#define DPL_ABSTRACT_SOCKET_H + +#include +#include +#include +#include +#include + +namespace DPL { +namespace Socket { +namespace AbstractSocketEvents { +// Successfuly connected to server socket +DECLARE_GENERIC_EVENT_0(ConnectedEvent) + +// New connection occurred and need to be accepted +DECLARE_GENERIC_EVENT_0(AcceptEvent) + +// Connection has read data waiting +DECLARE_GENERIC_EVENT_0(ReadEvent) + +// Connection write buffer is now empty again and ready to write more +DECLARE_GENERIC_EVENT_0(WriteEvent) +} // namespace AbstractSocketEvents + +class AbstractSocket : + public AbstractWaitableInputOutput, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport, + public DPL::Event::EventSupport +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) ///< Base abstract + // socket exception + + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) ///< Fatal error + // occurred during + // open socket + // descriptor. Socket + // state is + // inconsistent and + // it should be not + // used anymore. + + DECLARE_EXCEPTION_TYPE(Base, ConnectFailed) ///< Fatal error + // occurred during + // connect. Socket + // state is + // inconsistent and + // it should be not + // used anymore. + ///< Warning: This + // exception does not + // mean that socket + // did not succeed to + // connect, see + // CannotConnect + ///< for this + // specific scenario + + DECLARE_EXCEPTION_TYPE(Base, SetNonBlockingFailed) ///< Fatal error + // occurred during + // setting socket to + // non-blocking mode. + // Socket state is + // inconsistent and + // it should be not + // used anymore. + + DECLARE_EXCEPTION_TYPE(Base, BindFailed) ///< Fatal error + // occurred during + // bind. Socket state + // is inconsistent + // and it should be + // not used anymore. + + DECLARE_EXCEPTION_TYPE(Base, AcceptFailed) ///< Fatal error + // occurred during + // accept. Socket + // state is + // inconsistent and + // it should be not + // used anymore. + + DECLARE_EXCEPTION_TYPE(Base, ListenFailed) ///< Fatal error + // occurred during + // listen. Socket + // state is + // inconsistent and + // it should be not + // used anymore. + + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) ///< Fatal error + // occurred during + // close. Socket + // state is + // inconsistent and + // it should be not + // used anymore. + + DECLARE_EXCEPTION_TYPE(Base, ReadFailed) ///< Fatal error + // occurred during + // read. Socket state + // is inconsistent + // and it should be + // not used anymore. + ///< Warning: This + // exception does not + // mean that + // connection was + // broken, see + // ConnectionBroken + ///< for this + // specific scenario + + DECLARE_EXCEPTION_TYPE(Base, WriteFailed) ///< Fatal error + // occurred during + // write. Socket + // state is + // inconsistent and + // it should be not + // used anymore. + ///< Warning: This + // exception does not + // mean that + // connection was + // broken, see + // ConnectionBroken + ///< for this + // specific scenario + + DECLARE_EXCEPTION_TYPE(Base, GetPeerNameFailed) ///< Fatal error + // occurred during + // getpeername or + // getsockname. + // Socket state is + // inconsistent and + // it should be not + // used anymore. + + DECLARE_EXCEPTION_TYPE(Base, CannotConnect) ///< Cannot connect + // to remote socket. + // This is not fatal + // error, socket + // state is still + // consistent and it + // can be + // reconnected. + + DECLARE_EXCEPTION_TYPE(Base, ConnectionBroken) ///< Connection was + // broken. This is + // not fatal error, + // socket state is + // still consistent + // and it can be + // reconnected. + }; + + public: + virtual ~AbstractSocket() {} + + // Connect to remote host + virtual void Connect(const Address &address) = 0; + + // Open empty, unconnected socket + virtual void Open() = 0; + + // Close connection + virtual void Close() = 0; + + // Bind server socket address + virtual void Bind(const Address &address) = 0; + + // Begin listening for incoming connections + virtual void Listen(int backlog) = 0; + + // Accept waiting connection and create derived class connection + // One should cast resulting pointer to derived class + virtual AbstractSocket *Accept() = 0; + + // Local socket address + virtual Address GetLocalAddress() const = 0; + + // Remote socket address + virtual Address GetRemoteAddress() const = 0; +}; +} +} // namespace DPL + +#endif // DPL_ABSTRACT_SOCKET_H diff --git a/modules/socket/include/dpl/socket/generic_socket.h b/modules/socket/include/dpl/socket/generic_socket.h new file mode 100644 index 0000000..3ed9b86 --- /dev/null +++ b/modules/socket/include/dpl/socket/generic_socket.h @@ -0,0 +1,934 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of generic socket + */ +#ifndef DPL_GENERIC_SOCKET_H +#define DPL_GENERIC_SOCKET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Socket { +// +// Generic abstract socket implementation +// Execution context is inherited +// +template +class GenericSocket : + public AbstractSocket, + private WaitableHandleWatchSupport::WaitableHandleListener +{ + protected: + /** + * Translate generic Address to specific socket kernel structure + * + * @warning Must be implemented in derived class + */ + virtual std::pair TranslateAddressGenericToSpecific( + const Address &address) const = 0; + + /** + * Translate specific socket kernel structure to generic Address + * + * @warning Must be implemented in derived class + */ + virtual Address TranslateAddressSpecificToGeneric(sockaddr *, + socklen_t) const = 0; + + /** + * Get specific socket kernel structure size + * + * @warning Must be implemented in derived class + */ + virtual socklen_t GetSpecificAddressSize() const = 0; + + /** + * Alloc specific implementation of socket from descriptor + * + * @warning Must be implemented in derived class + */ + virtual SocketType *AllocAcceptedSpecificSocket() const = 0; + + /** + * Alloc specific implementation of socket descriptor + * + * @warning Must be implemented in derived class + */ + virtual int AllocSpecificDescriptor() const = 0; + + private: + // Constants + static const size_t DEFAULT_READ_BUFFER_SIZE = 4096; + + // Socket handle + int m_socket; // FIXME: Consider generalization to WaitableHandle upon + // leaving nix platform + + // Internal state + enum InternalState + { + InternalState_None, ///< Not connected and not listening state + InternalState_Prepare, ///< Descriptor allocated, but not connected + InternalState_Listening, ///< Listening state + InternalState_Connecting, ///< Connecting state + InternalState_Connected ///< Connected state + }; + + InternalState m_internalState; + + void SetNonBlocking() + { + // Set non-blocking mode + if (fcntl(m_socket, F_SETFL, O_NONBLOCK | + fcntl(m_socket, F_GETFL)) == -1) + { + Throw(AbstractSocket::Exception::SetNonBlockingFailed); + } + } + + // WaitableHandleWatchSupport::WaitableHandleListener + virtual void OnWaitableHandleEvent(WaitableHandle waitableHandle, + WaitMode::Type mode) + { + (void)waitableHandle; + Assert(waitableHandle == m_socket); + + switch (m_internalState) { + case InternalState_None: + break; + + case InternalState_Prepare: + Assert(0 && "Invalid internal generic socket state!"); + break; + + case InternalState_Listening: + Assert(mode == WaitMode::Read); + + // New client waiting for accept + DPL::Event::EventSupport:: + EmitEvent(AbstractSocketEvents::AcceptEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); + + // Done + break; + + case InternalState_Connecting: + Assert(mode == WaitMode::Write); + + // Connected to server + RemoveConnectWatch(); + m_internalState = InternalState_Connected; + + // Add read watch + AddReadWatch(); + + // Emit event + DPL::Event::EventSupport:: + EmitEvent(AbstractSocketEvents::ConnectedEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); + + // Done + break; + + case InternalState_Connected: + if (mode == WaitMode::Read) { + // Emit ReadEvent + DPL::Event::EventSupport:: + EmitEvent(AbstractSocketEvents::ReadEvent( + EventSender( + this)), DPL::Event::EmitMode::Queued); + } else if (mode == WaitMode::Write) { + // Emit WriteEvent + DPL::Event::EventSupport:: + EmitEvent(AbstractSocketEvents::WriteEvent( + EventSender( + this)), DPL::Event::EmitMode::Queued); + } else { + Assert(0); + } + + break; + + default: + Assert(0); + break; + } + } + + void AddAcceptWatch() + { + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch( + this, + m_socket, + WaitMode::Read); + } + + void RemoveAcceptWatch() + { + WaitableHandleWatchSupport::InheritedContext()-> + RemoveWaitableHandleWatch(this, m_socket, WaitMode::Read); + } + + void AddConnectWatch() + { + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch( + this, + m_socket, + WaitMode::Write); + } + + void RemoveConnectWatch() + { + WaitableHandleWatchSupport::InheritedContext()-> + RemoveWaitableHandleWatch(this, m_socket, WaitMode::Write); + } + + void AddReadWatch() + { + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch( + this, + m_socket, + WaitMode::Read); + } + + void RemoveReadWatch() + { + WaitableHandleWatchSupport::InheritedContext()-> + RemoveWaitableHandleWatch(this, m_socket, WaitMode::Read); + } + + void AddWriteWatch() + { + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch( + this, + m_socket, + WaitMode::Write); + } + + void RemoveWriteWatch() + { + WaitableHandleWatchSupport::InheritedContext()-> + RemoveWaitableHandleWatch(this, m_socket, WaitMode::Write); + } + + public: + GenericSocket() : + m_socket(-1), + m_internalState(InternalState_None) + {} + + virtual ~GenericSocket() + { + // Always ensure to close socket + Try + { + Close(); + } + Catch(Exception::CloseFailed) + { + LogPedantic("Close failed and ignored"); + } + + // Check consistency + Assert(m_socket == -1); + } + + virtual void Open() + { + if (m_internalState != InternalState_None) { + ThrowMsg(AbstractSocket::Exception::OpenFailed, + "Invalid socket state, should be 'None'"); + } + + LogPedantic("Opening socket..."); + + // Check consistency + Assert(m_socket == -1); + + // Allocate specific socket descriptor + m_socket = AllocSpecificDescriptor(); + + // Set socket non-blocking + SetNonBlocking(); + + // State is prepared + m_internalState = InternalState_Prepare; + + LogPedantic("Socket opened"); + } + + virtual void Connect(const Address &address) + { + if (m_internalState != InternalState_Prepare) { + ThrowMsg(AbstractSocket::Exception::ConnectFailed, + "Invalid socket state, should be 'Prepare'"); + } + + LogPedantic("Connecting to: " << address.ToString()); + + // Try to convert address + std::pair socketAddress; + + Try + { + // Translate address to specific socket address struct + socketAddress = TranslateAddressGenericToSpecific(address); + } + Catch(Address::Exception::InvalidAddress) + { + // This address is invalid. Cannot connect. + ReThrowMsg(AbstractSocket::Exception::ConnectFailed, + address.ToString()); + } + + // Do connect + int result = + TEMP_FAILURE_RETRY(connect(m_socket, socketAddress.first, + socketAddress.second)); + + if (result == 0) { + // Immediate connect + LogPedantic("Immediate connected to: " << address.ToString()); + + // Add read watch + AddReadWatch(); + m_internalState = InternalState_Connected; + + // Emit connected event + DPL::Event::EventSupport:: + EmitEvent(AbstractSocketEvents::ConnectedEvent( + EventSender(this)), DPL::Event::EmitMode::Queued); + } else { + if (errno == EINTR || errno == EINPROGRESS) { + LogPedantic( + "Asynchronous connect in progress: " << address.ToString()); + + // Connecting in progress + AddConnectWatch(); + m_internalState = InternalState_Connecting; + } else { + // Free translation structure + free(socketAddress.first); + + // Error occurred + ThrowMsg(AbstractSocket::Exception::ConnectFailed, + address.ToString()); + } + } + + // Free translation structure + free(socketAddress.first); + } + + virtual void Close() + { + if (m_internalState == InternalState_None) { + return; + } + + Assert(m_socket != -1); + + if (m_internalState == InternalState_Listening) { + // Remove watch in listening state + LogPedantic("Removing accept watch"); + RemoveAcceptWatch(); + m_internalState = InternalState_None; + } else if (m_internalState == InternalState_Connecting) { + // Remove watch in connecting state + LogPedantic("Removing connect watch"); + RemoveConnectWatch(); + m_internalState = InternalState_None; + } else if (m_internalState == InternalState_Connected) { + // Remove watch in connected state + LogPedantic("Removing read watch"); + RemoveReadWatch(); + m_internalState = InternalState_None; + } else { + // State must be just prepared only + Assert(m_internalState == InternalState_Prepare); + } + + if (TEMP_FAILURE_RETRY(close(m_socket)) == -1) { + Throw(Exception::CloseFailed); + } + + // Reset socket + m_socket = -1; + + // Reset socket state + m_internalState = InternalState_None; + + LogPedantic("Socket closed"); + } + + virtual void Bind(const Address &address) + { + if (m_internalState != InternalState_Prepare) { + ThrowMsg(AbstractSocket::Exception::BindFailed, + "Invalid socket state, should be 'Prepare'"); + } + + LogPedantic( + "Binding to: " << address.GetAddress() << ":" << address.GetPort()); + + // Translate address to specific socket address struct + std::pair socketAddress = TranslateAddressGenericToSpecific( + address); + + // Do bind + if (::bind(m_socket, socketAddress.first, + socketAddress.second) == -1) + { + ThrowMsg(AbstractSocket::Exception::BindFailed, address.ToString()); + } + + // Free translation structure + free(socketAddress.first); + + // Show info + LogPedantic( + "Bound to address: " << address.GetAddress() << ":" << + address.GetPort()); + } + + virtual void Listen(int backlog) + { + if (m_internalState != InternalState_Prepare) { + ThrowMsg(AbstractSocket::Exception::ListenFailed, + "Invalid socket state, should be 'None'"); + } + + LogPedantic("Starting to listen..."); + + // Do listen + if (listen(m_socket, backlog) != 0) { + Throw(AbstractSocket::Exception::ListenFailed); + } + + // Begin read watch + AddAcceptWatch(); + m_internalState = InternalState_Listening; + + LogPedantic("Listen started"); + } + + virtual AbstractSocket *Accept() + { + if (m_internalState != InternalState_Listening) { + ThrowMsg(AbstractSocket::Exception::AcceptFailed, + "Invalid socket state, should be 'Listening'"); + } + + LogPedantic("Accepting..."); + + // Do listen + socklen_t length = 0; + int client = TEMP_FAILURE_RETRY(accept(m_socket, NULL, &length)); + + LogPedantic("Socket accept returned " << client); + if (client == -1) { + // Check if there is any client waiting + if (errno == EWOULDBLOCK || errno == EAGAIN) { + return NULL; + } + int err = errno; + if (errno == ENOENT) { + return NULL; + } + LogPedantic("throwing error. errrno " << err); + // Error occurred + Throw(AbstractSocket::Exception::AcceptFailed); + } + + LogPedantic("Accepted client. Seting up..."); + + // Create derived class type + GenericSocket *acceptedSocket = AllocAcceptedSpecificSocket(); + + // Save client socket specific descriptor + acceptedSocket->m_socket = client; + + // Enter proper states and add read watch + acceptedSocket->AddReadWatch(); + acceptedSocket->m_internalState = InternalState_Connected; + + // Set non-blocking mode for new socket + acceptedSocket->SetNonBlocking(); + + // Show info + LogPedantic("Accepted client set up"); + + // return new conneced client socket + return acceptedSocket; + } + + virtual Address GetLocalAddress() const + { + // FIXME: Additional internal state check + + socklen_t length = GetSpecificAddressSize(); + ScopedFree address(static_cast(calloc( + static_cast< + size_t>( + length), + 1))); + + if (getsockname(m_socket, address.Get(), &length) == -1) { + ThrowMsg(AbstractSocket::Exception::GetPeerNameFailed, + "Failed to get local address"); + } + + return TranslateAddressSpecificToGeneric(address.Get(), length); + } + + virtual Address GetRemoteAddress() const + { + // FIXME: Additional internal state check + + socklen_t length = GetSpecificAddressSize(); + ScopedFree address(static_cast(calloc( + static_cast< + size_t>( + length), + 1))); + + if (getpeername(m_socket, address.Get(), &length) == -1) { + ThrowMsg(AbstractSocket::Exception::GetPeerNameFailed, + "Failed to get remote address"); + } + + return TranslateAddressSpecificToGeneric(address.Get(), length); + } + + virtual BinaryQueueAutoPtr Read(size_t size) + { + if (m_internalState != InternalState_Connected) { + ThrowMsg(AbstractSocket::Exception::AcceptFailed, + "Invalid socket state, should be 'Connected'"); + } + + Try + { + // Adjust bytes to be read + size_t bytesToRead = size > + DEFAULT_READ_BUFFER_SIZE ? DEFAULT_READ_BUFFER_SIZE : size; + + // Malloc default read buffer size + // It is unmanaged, so it can be then attached directly to binary + // queue + void *buffer = malloc(bytesToRead); + + if (buffer == NULL) { + throw std::bad_alloc(); + } + + // Receive bytes from socket + ssize_t result = + TEMP_FAILURE_RETRY(recv(m_socket, buffer, bytesToRead, 0)); + + if (result > 0) { + // Succedded to read socket data + BinaryQueueAutoPtr binaryQueue(new BinaryQueue()); + + // Append unmanaged memory + binaryQueue->AppendUnmanaged(buffer, + result, + &BinaryQueue::BufferDeleterFree, + NULL); + + // Return buffer + return binaryQueue; + } else if (result == 0) { + // Socket was gracefuly closed + free(buffer); + + // Return empty buffer + return BinaryQueueAutoPtr(new BinaryQueue()); + } else { + // Must first save errno value, because it may be altered + int lastErrno = errno; + + // Free buffer + free(buffer); + + // Interpret error result + switch (lastErrno) { + case EAGAIN: // = EWOULDBLOCK + // + // * The socket's file descriptor is marked O_NONBLOCK and + // no data is waiting + // to be received; or MSG_OOB is set and no out-of-band + // data is available + // and either the socket's file descriptor is marked + // O_NONBLOCK or the socket + // does not support blocking to await out-of-band data. + // + // return null data buffer to indicate no data waiting + // + return BinaryQueueAutoPtr(); + + case EBADF: + // + // * The socket argument is not a valid file descriptor. + // + // This is internal error + // + ThrowMsg(CommonException::InternalError, + "Invalid socket descriptor"); + + case ECONNRESET: + // + // * A connection was forcibly closed by a peer. + // + // In result, we can interpret this error as a broken + // connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case EINTR: + // + // * The recv() function was interrupted by a signal that + // was caught, before any + // data was available. + // + // No interrupt here is expected, due to fact that we used + // TEMP_FAILURE_RETRY + // + ThrowMsg(CommonException::InternalError, + "Unexpected interrupt occurred"); + + case EINVAL: + // + // * The MSG_OOB flag is set and no out-of-band data is + // available. + // + // We did not specified OOB data. This is an error. + // + ThrowMsg(CommonException::InternalError, + "Unexpected OOB error occurred"); + + case ENOTCONN: + // + // * A receive is attempted on a connection-mode socket that + // is not connected. + // + // FIXME: Is this proper exception here ? + // + ThrowMsg(CommonException::InternalError, + "Socket is not connected"); + + case ENOTSOCK: + // + // * The socket argument does not refer to a socket. + // + ThrowMsg(CommonException::InternalError, + "Handle is not a socket"); + + case EOPNOTSUPP: + // + // * The specified flags are not supported for this socket + // type or protocol. + // + ThrowMsg(CommonException::InternalError, + "Socket flags not supported"); + + case ETIMEDOUT: + // + // * The connection timed out during connection + // establishment, or due to a transmission timeout on active + // connection. + // + // In result, we can interpret this error as a broken + // connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case EIO: + // + // * An I/O error occurred while reading from or writing to + // the file system. + // + // In result, we can interpret this error as a broken + // connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case ENOBUFS: + // + // * Insufficient resources were available in the system to + // perform the operation. + // + ThrowMsg(CommonException::InternalError, + "Insufficient system resources"); + + case ENOMEM: + // + // * Insufficient memory was available to fulfill the + // request. + // + ThrowMsg(CommonException::InternalError, + "Insufficient system memory"); + + default: + // Some kernel error occurred, should never happen + ThrowMsg(CommonException::InternalError, + "Unknown kernel read error returned"); + break; + } + } + } + Catch(CommonException::InternalError) + { + // If any internal error occurred, this is fatal for Write method + // interpret this as WriteError exception and rethrow + ReThrow(AbstractSocket::Exception::ReadFailed); + } + } + + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize) + { + if (m_internalState != InternalState_Connected) { + ThrowMsg(AbstractSocket::Exception::AcceptFailed, + "Invalid socket state, should be 'Connected'"); + } + + Try + { + // Adjust write size + if (bufferSize > buffer.Size()) { + bufferSize = buffer.Size(); + } + + // FIXME: User write visitor to write ! + // WriteVisitor visitor + + ScopedFree flattened(malloc(bufferSize)); + buffer.Flatten(flattened.Get(), bufferSize); + + // Linux: MSG_NOSIGNAL is supported, but it is not an ideal solution + // FIXME: Should we setup signal PIPE ignoring for whole process ? + // In BSD, there is: setsockopt(c, SOL_SOCKET, SO_NOSIGPIPE, (void + // *)&on, sizeof(on)) + ssize_t result = + TEMP_FAILURE_RETRY(send(m_socket, flattened.Get(), bufferSize, + MSG_NOSIGNAL)); + + if (result > 0) { + // Successfuly written some bytes + return static_cast(result); + } else if (result == 0) { + // This is abnormal result + ThrowMsg(CommonException::InternalError, + "Invalid socket write result, 0 bytes written"); + } else if (result == -1) { + // Interpret error result + switch (errno) { + case EAGAIN: // = EWOULDBLOCK + // + // * The socket's file descriptor is marked O_NONBLOCK and + // the requested operation would block. + // + // We should wait for writability + // + return 0; + + case EBADF: + // + // * The socket argument is not a valid file descriptor. + // + // This is internal error + // + ThrowMsg(CommonException::InternalError, + "Invalid socket descriptor"); + + case ECONNRESET: + // + // * A connection was forcibly closed by a peer. + // + // In result, we can interpret this error as a broken + // connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case EDESTADDRREQ: + // + // * The socket is not connection-mode and no peer address + // is set. + // + // FIXME: Is this proper exception here ? + // + ThrowMsg(CommonException::InternalError, + "Socket is not connected"); + + case EINTR: + // + // * A signal interrupted send() before any data was + // transmitted. + // + // No interrupt here is expected, due to fact that we used + // TEMP_FAILURE_RETRY + // + ThrowMsg(CommonException::InternalError, + "Unexpected interrupt occurred"); + + case EMSGSIZE: + // + // * The message is too large to be sent all at once, as the + // socket requires. + // + // FIXME: Is this proper exception here ? + // + ThrowMsg(CommonException::InternalError, + "Socket message is too big"); + + case ENOTCONN: + // + // * The socket is not connected or otherwise has not had + // the peer pre-specified. + // + // FIXME: Is this proper exception here ? + // + ThrowMsg(CommonException::InternalError, + "Socket is not connected"); + + case ENOTSOCK: + // + // * The socket argument does not refer to a socket. + // + ThrowMsg(CommonException::InternalError, + "Handle is not a socket"); + + case EOPNOTSUPP: + // + // * The socket argument is associated with a socket that + // does not support one or more of the values set in flags. + // + ThrowMsg(CommonException::InternalError, + "Socket flags not supported"); + + case EPIPE: + // + // * The socket is shut down for writing, or the socket is + // connection-mode and + // is no longer connected. In the latter case, and if the + // socket is of type + // SOCK_STREAM, the SIGPIPE signal is generated to the + // calling thread. + // + // In result, we can interpret this error as a broken + // connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case EACCES: + // + // * The calling process does not have the appropriate + // privileges. + // + // Priviledges might have changed. + // In result, we can interpret this error as a broken + // connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case EIO: + // + // * An I/O error occurred while reading from or writing to + // the file system. + // + // In result, we can interpret this error as a broken + // connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case ENETDOWN: + // + // * The local network interface used to reach the + // destination is down. + // + // In result, we can interpret this error as a broken + // connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case ENETUNREACH: + // + // * No route to the network is present. + // + // In result, we can interpret this error as a broken + // connection + // + Throw(AbstractSocket::Exception::ConnectionBroken); + + case ENOBUFS: + // + // * Insufficient resources were available in the system to + // perform the operation. + // + ThrowMsg(CommonException::InternalError, + "Insufficient system resources"); + + default: + // Some kernel error occurred, should never happen + ThrowMsg(CommonException::InternalError, + "Unknown kernel write error returned"); + break; + } + } + } + Catch(CommonException::InternalError) + { + // If any internal error occurred, this is fatal for Write method + // interpret this as WriteError exception and rethrow + ReThrow(AbstractSocket::Exception::WriteFailed); + } + + // Does not apply + return 0; + } + + // AbstractWaitableInput + virtual WaitableHandle WaitableReadHandle() const + { + return m_socket; + } + + // AbstractWaitableOutput + virtual WaitableHandle WaitableWriteHandle() const + { + return m_socket; + } +}; +} +} // namespace DPL + +#endif // DPL_GENERIC_SOCKET_H diff --git a/modules/socket/include/dpl/socket/unix_socket.h b/modules/socket/include/dpl/socket/unix_socket.h new file mode 100644 index 0000000..37614ce --- /dev/null +++ b/modules/socket/include/dpl/socket/unix_socket.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file of unix socket + */ +#ifndef DPL_UNIX_SOCKET_H +#define DPL_UNIX_SOCKET_H + +#include +#include + +namespace DPL { +namespace Socket { +class UnixSocket : + public GenericSocket +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, CreateFailed) + }; + + protected: + /** + * Translate generic Address to specific socket kernel structure + */ + virtual std::pair TranslateAddressGenericToSpecific( + const Address &address) const; + + /** + * Translate specific socket kernel structure to generic Address + */ + virtual Address TranslateAddressSpecificToGeneric(sockaddr *, + socklen_t) const; + + /** + * Get specific socket kernel structure size + */ + virtual socklen_t GetSpecificAddressSize() const; + + /** + * Alloc specific implementation of socket from descriptor + */ + virtual UnixSocket *AllocAcceptedSpecificSocket() const; + + /** + * Alloc specific implementation of socket descriptor + */ + virtual int AllocSpecificDescriptor() const; + + public: + UnixSocket(); + + virtual void Bind(const Address &address); +}; +} +} // namespace DPL + +#endif // DPL_GENERIC_SOCKET_H diff --git a/modules/socket/include/dpl/socket/waitable_input_output_execution_context_support.h b/modules/socket/include/dpl/socket/waitable_input_output_execution_context_support.h new file mode 100644 index 0000000..f02df51 --- /dev/null +++ b/modules/socket/include/dpl/socket/waitable_input_output_execution_context_support.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_input_output_execution_context_support.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the header file for waitable input-output execution + * context support + */ +#ifndef DPL_WAITABLE_INPUT_OUTPUT_EXECUTION_CONTEXT_SUPPORT_H +#define DPL_WAITABLE_INPUT_OUTPUT_EXECUTION_CONTEXT_SUPPORT_H + +#include +#include +#include + +namespace DPL { +namespace Socket { +class WaitableInputOutputExecutionContextSupport : + private WaitableHandleWatchSupport::WaitableHandleListener +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, AlreadyOpened) + DECLARE_EXCEPTION_TYPE(Base, NotOpened) + DECLARE_EXCEPTION_TYPE(Base, OpenFailed) + DECLARE_EXCEPTION_TYPE(Base, CloseFailed) + }; + + private: + bool m_opened; + AbstractWaitableInputOutput *m_waitableInputOutput; + + // Watch state + bool m_hasReadWatch; + bool m_hasWriteWatch; + + void AddReadWatch(); + void RemoveReadWatch(); + void AddWriteWatch(); + void RemoveWriteWatch(); + + void ReadInput(); + + void CheckedRemoveReadWatch(); + void CheckedRemoveWriteWatch(); + + void CheckedRemoveReadWriteWatch(); + + virtual void OnWaitableHandleEvent(WaitableHandle waitableHandle, + WaitMode::Type mode); + + protected: + // Incoming/Outgoing streams + BinaryQueue m_inputStream; + BinaryQueue m_outputStream; + + // Support calbback methods + virtual void OnInputStreamRead() = 0; + virtual void OnInputStreamClosed() = 0; + virtual void OnInputStreamBroken() = 0; + + // Trigger feeding output - after updating output stream + void FeedOutput(); + + // Open/Close destination waitable input-output + void Open(AbstractWaitableInputOutput *waitableInputOutput); + void Close(); + + public: + /** + * Constructor + */ + explicit WaitableInputOutputExecutionContextSupport(); + + /** + * Destructor + */ + virtual ~WaitableInputOutputExecutionContextSupport(); +}; +} +} // namespace DPL + +#endif // DPL_WAITABLE_INPUT_OUTPUT_EXECUTION_CONTEXT_SUPPORT_H diff --git a/modules/socket/src/generic_socket.cpp b/modules/socket/src/generic_socket.cpp new file mode 100644 index 0000000..aff2d74 --- /dev/null +++ b/modules/socket/src/generic_socket.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file generic_socket.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of generic socket + */ +#include +#include + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/modules/socket/src/unix_socket.cpp b/modules/socket/src/unix_socket.cpp new file mode 100644 index 0000000..36bff51 --- /dev/null +++ b/modules/socket/src/unix_socket.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file unix_socket.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of unix socket + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Socket { +UnixSocket::UnixSocket() +{} + +int UnixSocket::AllocSpecificDescriptor() const +{ + LogPedantic("Creating UNIX socket..."); + + // Create new descriptor + int newSocket = socket(AF_UNIX, SOCK_STREAM, 0); + + if (newSocket == -1) { + Throw(Exception::CreateFailed); + } + + LogPedantic("UNIX socket created"); + + // Return new descriptor + return newSocket; +} + +std::pair UnixSocket::TranslateAddressGenericToSpecific( + const Address &address) const +{ + // Allocate new socket address structure + sockaddr_un *sockAddress = + static_cast(malloc(sizeof(sockaddr_un))); + if (!sockAddress) { + throw std::bad_alloc(); + } + + memset(sockAddress, 0, sizeof(sockaddr_un)); + + // Copy address properties + sockAddress->sun_family = AF_UNIX; + strncpy(sockAddress->sun_path, address.GetAddress().c_str(), + sizeof(sockAddress->sun_path) - 1); + + //Prevent buffer overflows + sockAddress->sun_path[sizeof(sockAddress->sun_path) - 1] = '\0'; + + // Set proper address length + socklen_t sockAddressLength = SUN_LEN(sockAddress); + + // Return new translated address + return std::make_pair(reinterpret_cast(sockAddress), + sockAddressLength); +} + +Address UnixSocket::TranslateAddressSpecificToGeneric(sockaddr *address, + socklen_t) const +{ + // FIXME: Constrain check ? + sockaddr_un *unixAddress = reinterpret_cast(address); + return Address(unixAddress->sun_path); +} + +socklen_t UnixSocket::GetSpecificAddressSize() const +{ + return static_cast(sizeof(sockaddr_un)); +} + +UnixSocket *UnixSocket::AllocAcceptedSpecificSocket() const +{ + return new UnixSocket(); +} + +void UnixSocket::Bind(const Address &address) +{ + // Always remove socket file if any + unlink(address.GetAddress().c_str()); + + // Call base implementation + GenericSocket::Bind(address); + + // Always set proper permissions to the socket file + if (chmod(address.GetAddress().c_str(), 0777) < 0) { + LogError( + "Error setting permissions to the socket file. Errno " << + strerror(errno)); + } +} +} +} // namespace DPL diff --git a/modules/socket/src/waitable_input_output_execution_context_support.cpp b/modules/socket/src/waitable_input_output_execution_context_support.cpp new file mode 100644 index 0000000..35635b5 --- /dev/null +++ b/modules/socket/src/waitable_input_output_execution_context_support.cpp @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file waitable_input_output_execution_context_support.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of waitable input-output + * execution context support + */ +#include +#include +#include +#include // FIXME: Remove !!! +#include +#include + +namespace DPL { +namespace Socket { +namespace // anonymous +{ +const size_t DEFAULT_READ_SIZE = 2048; +} // namespace anonymous + +WaitableInputOutputExecutionContextSupport:: + WaitableInputOutputExecutionContextSupport() : + m_opened(false), + m_waitableInputOutput(NULL), + m_hasReadWatch(false), + m_hasWriteWatch(false) +{} + +WaitableInputOutputExecutionContextSupport::~ +WaitableInputOutputExecutionContextSupport() +{ + // Ensure support is closed + Close(); +} + +void WaitableInputOutputExecutionContextSupport::Open( + AbstractWaitableInputOutput *inputOutput) +{ + if (m_opened) { + Throw(Exception::AlreadyOpened); + } + + LogPedantic("Opening waitable input-output execution context support..."); + + // Save IO handle + m_waitableInputOutput = inputOutput; + + // Register read watch + Assert(m_hasReadWatch == false); + + AddReadWatch(); + m_hasReadWatch = true; + + // Done + m_opened = true; + + LogPedantic("Waitable input-output execution context support opened"); +} + +void WaitableInputOutputExecutionContextSupport::Close() +{ + if (!m_opened) { + return; + } + + LogPedantic("Closing waitable input-output execution context support..."); + + // Remove read and write watches + CheckedRemoveReadWriteWatch(); + + // Set proper state + m_opened = false; + + LogPedantic("Waitable input-output execution context support closed"); +} + +void WaitableInputOutputExecutionContextSupport::AddReadWatch() +{ + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch( + this, + m_waitableInputOutput + ->WaitableReadHandle(), + WaitMode + ::Read); +} + +void WaitableInputOutputExecutionContextSupport::RemoveReadWatch() +{ + WaitableHandleWatchSupport::InheritedContext()->RemoveWaitableHandleWatch( + this, + m_waitableInputOutput->WaitableReadHandle(), + WaitMode::Read); +} + +void WaitableInputOutputExecutionContextSupport::AddWriteWatch() +{ + WaitableHandleWatchSupport::InheritedContext()->AddWaitableHandleWatch( + this, + m_waitableInputOutput + ->WaitableWriteHandle(), + WaitMode + ::Write); +} + +void WaitableInputOutputExecutionContextSupport::RemoveWriteWatch() +{ + WaitableHandleWatchSupport::InheritedContext()->RemoveWaitableHandleWatch( + this, + m_waitableInputOutput->WaitableWriteHandle(), + WaitMode::Write); +} + +void WaitableInputOutputExecutionContextSupport::CheckedRemoveReadWatch() +{ + if (!m_hasReadWatch) { + return; + } + + RemoveReadWatch(); + m_hasReadWatch = false; +} + +void WaitableInputOutputExecutionContextSupport::CheckedRemoveWriteWatch() +{ + if (!m_hasWriteWatch) { + return; + } + + RemoveWriteWatch(); + m_hasWriteWatch = false; +} + +void WaitableInputOutputExecutionContextSupport::CheckedRemoveReadWriteWatch() +{ + // Remove read watch if any + CheckedRemoveReadWatch(); + + // Remove write watch if any + CheckedRemoveWriteWatch(); +} + +void WaitableInputOutputExecutionContextSupport::OnWaitableHandleEvent( + WaitableHandle waitableHandle, + WaitMode::Type mode) +{ + (void)waitableHandle; + + switch (mode) { + case WaitMode::Read: + LogPedantic("Read event occurred"); + + // Read and parse bytes + ReadInput(); + + // Done + break; + + case WaitMode::Write: + LogPedantic("Write event occurred"); + + // Push bytes and unregister from write event + FeedOutput(); + + // Unregister write watch only if no more data is available + if (m_outputStream.Empty()) { + Assert(m_hasWriteWatch == true); + CheckedRemoveWriteWatch(); + } + + // Done + break; + + default: + Assert(0); + break; + } +} + +void WaitableInputOutputExecutionContextSupport::ReadInput() +{ + LogPedantic("Reading input bytes"); + + Try + { + BinaryQueueAutoPtr inputBuffer = m_waitableInputOutput->Read( + DEFAULT_READ_SIZE); + + if (inputBuffer.get() == NULL) { + // No data, should not occur + LogPedantic("WARNING: Spontaneous ReadSocket occurred"); + return; + } + + if (inputBuffer->Empty()) { + // Connection was closed + OnInputStreamClosed(); + + // Unregister from further event insisting + Assert(m_hasReadWatch == true); + CheckedRemoveReadWriteWatch(); + + // Set proper state + m_opened = false; + + // Done + return; + } + + LogPedantic("Read " << inputBuffer->Size() << " input bytes"); + + // Append all read data + m_inputStream.AppendMoveFrom(*inputBuffer); + } + Catch(AbstractSocket::Exception::ConnectionBroken) + { + //FIXME: Inproper exception abstraction!!! + // Some errors occurred while feeding abstract IO + // Interpret connection broken errors, and pass futher other ones + LogPedantic("Abstract IO connection was broken during read"); + + // Signal broken connection + OnInputStreamBroken(); + + // Unregister from further event insisting + Assert(m_hasReadWatch == true); + CheckedRemoveReadWriteWatch(); + + // Set proper state + m_opened = false; + + // Do not continue + return; + } + + // Interpret data + OnInputStreamRead(); +} + +void WaitableInputOutputExecutionContextSupport::FeedOutput() +{ + if (!m_opened) { + Throw(Exception::NotOpened); + } + + // Anything to feed ? + if (m_outputStream.Empty()) { + return; + } + + // OK to feed output + LogPedantic("Feeding output"); + + Try + { + // Try to write some bytes + size_t bytes = m_waitableInputOutput->Write(m_outputStream, + m_outputStream.Size()); + + if (bytes < m_outputStream.Size()) { + // Start exhaustive output feeding if it is blocked and not already + // started + if (!m_hasWriteWatch) { + AddWriteWatch(); + m_hasWriteWatch = true; + + LogPedantic("Started exhaustive output feeding"); + } + } + + // Some bytes were written, consume them + m_outputStream.Consume(bytes); + } + Catch(AbstractSocket::Exception::ConnectionBroken) // FIXME: Inproper + // exception abstraction + // !!! + { + // Some errors occurred while feeding abstract IO + // Interpret connection broken errors, and pass futher other ones + LogPedantic("Abstract IO connection was broken during write"); + + // Signal broken connection + OnInputStreamBroken(); + + // Unregister from further event insisting + Assert(m_hasReadWatch == true); + CheckedRemoveReadWriteWatch(); + + // Set proper state + m_opened = false; + + // Do not continue + return; + } +} +} +} // namespace DPL diff --git a/modules/support/config.cmake b/modules/support/config.cmake new file mode 100644 index 0000000..e2865f6 --- /dev/null +++ b/modules/support/config.cmake @@ -0,0 +1,26 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + + +SET(DPL_WRT_ENGINE_HEADERS + ${PROJECT_SOURCE_DIR}/modules/support/wrt_plugin_export.h + PARENT_SCOPE +) diff --git a/modules/support/wrt_plugin_export.h b/modules/support/wrt_plugin_export.h new file mode 100755 index 0000000..0cf4e37 --- /dev/null +++ b/modules/support/wrt_plugin_export.h @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file wrt_plugin_export.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for plugin export API + */ +#ifndef WRT_PLUGIN_EXPORT_H +#define WRT_PLUGIN_EXPORT_H + +#include + +/** + * Widget handle type + */ +typedef int widget_handle_t; + +/** + * Parameter which should be used during policy evaluation. + */ +typedef struct ace_param_s +{ + const char *name; + const char *value; +} ace_param_t; + +/** + * List of additional parameters which should be used during policy evaluation. + */ +typedef struct ace_param_list_s +{ + size_t count; + ace_param_t *param; +} ace_param_list_t; + +/** + * Contains list of device capabilities. Each device capability may have + * associated list of function params. + */ +typedef struct ace_device_cap_s +{ + size_t devcapsCount; + const char** dev_cap_names; + size_t paramsCount; + ace_param_list_t* params; +} ace_device_cap_t; + +/** + * List of device capabilities which must be check. + */ +typedef struct ace_device_capabilities_s +{ + size_t count; + const char **device_cap; +} ace_device_capabilities_t; + +/** + * List of api features that must be checked + */ +typedef struct ace_api_features_s +{ + size_t count; + const char **api_feature; +} ace_api_features_t; + +/** + * Data from request will be used to evaluate policy file. + */ +typedef struct ace_request_s +{ + widget_handle_t widget_handle; + const char* feature_api; + const char* function_name; + ace_device_capabilities_t device_capabilities; + ace_param_list_t param_list; +} ace_request_t; + +/** + * Data from request will be used to evaluate policy file. + */ +typedef struct ace_request_2_s +{ + widget_handle_t widget_handle; + ace_api_features_t api_features; + const char* function_name; + ace_device_cap_t device_capabilities; +} ace_request_2_t; + +/** + * info returned by plugin_api_check_access + */ +#define PLUGIN_API_ACCESS_GRANTED 1 +#define PLUGIN_API_ACCESS_DENIED 0 +#define PLUGIN_API_ACCESS_ERROR -1 + +typedef const void* java_script_context_t; + +typedef struct js_object_properties_s +{ + size_t count; + char** properties; +} js_object_properties_t; + +typedef const void* js_class_template_t; +typedef void* js_object_ref_t; +typedef const void* js_value_ref_t; + +typedef js_class_template_t (*js_class_template_getter)(void); +typedef void* (*js_class_constructor_cb_t)(js_class_template_t, + js_object_ref_t, size_t, + js_value_ref_t[], + js_value_ref_t*); + +typedef enum class_definition_type_e +{ + JS_CLASS, + JS_FUNCTION, + JS_INTERFACE +} class_definition_type_t; + +typedef enum class_definition_iframe_behaviour_e +{ + //object should not be initalized in iframes + //it is default one + NONE, + //object should be copied as reference to each iframe + REFERENCE, // deprecated + //object should be created for each iframe and NOT inform plugin + CREATE_INSTANCE +} class_definition_iframe_behaviour_t; + +typedef enum class_definition_iframe_notice_e +{ + //it is default one + NONE_NOTICE, + ALWAYS_NOTICE +} class_definition_iframe_notice_t; + +typedef enum class_definition_iframe_overlay_e +{ + IGNORED, + USE_OVERLAYED, //deprecated + OVERLAYED_BEFORE_ORIGINAL //deprecated +} class_definition_iframe_overlay_t; //deprecated + +typedef void* js_object_instance_t; +//global_context - id +typedef void (*iframe_loaded_cb)(java_script_context_t global_context, + js_object_instance_t iframe, + js_object_instance_t object); + +typedef void* (*js_function_impl)(void*); + +typedef struct class_definition_options_s +{ + class_definition_type_t type; + class_definition_iframe_behaviour_t iframe_option; + class_definition_iframe_notice_t iframe_notice; + class_definition_iframe_overlay_t iframe_overlay; //deprecated + iframe_loaded_cb cb; + void * private_data; + js_function_impl function; +} class_definition_options_t; + +/* + * list of device caps + */ +typedef struct devcaps_s +{ + char** deviceCaps; + size_t devCapsCount; +} devcaps_t; + +/* + * mapping from a feature to corresponding list of device capabilities + */ +typedef struct feature_devcaps_s +{ + char* feature_name; + devcaps_t devCaps; +} feature_devcaps_t; + +/* + * list of feature_devcaps_t structs + */ +typedef struct feature_mapping_s +{ + feature_devcaps_t* features; + size_t featuresCount; +} feature_mapping_t; + +typedef feature_mapping_t* pfeature_mapping_t; + +typedef pfeature_mapping_t (*features_getter)(void); + +typedef const devcaps_t* (*devcaps_getter)(pfeature_mapping_t /*features*/, + const char* /*featureName*/); +typedef void (*deinitializer)(pfeature_mapping_t /*features*/); + +typedef struct feature_mapping_interface_s +{ + features_getter featGetter; /* returns a list of api features */ + devcaps_getter dcGetter; /* + * for a given api feature returns a list of + * corresponding device capabilities + */ + + deinitializer release; /* as memory ownership of features is + * transfered to callee you have to call + * the release function ptr on features + */ +} feature_mapping_interface_t; + +/* + * This is a structure describing a JS entity template (a class, an interface + * or function), object name and it's parent class name (parent_name). JS + * entity will be bind to a parent class name (parent_name.js_entity_name). + * @param parent_name - parent name (ie Widget.Device) + * @param object_name - object name (DeviceStatus) + * @param interface_name - interface name (e.g. Widget) + * @param js_class_template_getter_fun - js_class_template required to create + * JS object + * @param js_class_consturctor_cb - constructor to call to when instance of + * certain interface is created + * @param private_data private data for object creator if required (usually + * NULL) + */ +typedef struct js_entity_definition_s +{ + const char *parent_name; + const char *object_name; + const char *interface_name; + js_class_template_getter js_class_template_getter_fun; + js_class_constructor_cb_t js_class_constructor_cb; + //class options may be null - default + class_definition_options_t* class_options; +} js_entity_definition_t; + +typedef const js_entity_definition_t *js_entity_definition_ptr_t; + +/** + * Plugin export names + */ +#define PLUGIN_WIDGET_START_PROC on_widget_start +#define PLUGIN_WIDGET_INIT_PROC on_widget_init +#define PLUGIN_WIDGET_STOP_PROC on_widget_stop +#define PLUGIN_FRAME_LOAD_PROC on_frame_load +#define PLUGIN_FRAME_UNLOAD_PROC on_frame_unload +#define PLUGIN_CLASS_MAP class_map +#define PLUGIN_GET_CLASS_PROC_MAP get_widget_class_map + +#define PLUGIN_WIDGET_START_PROC_NAME "on_widget_start" +#define PLUGIN_WIDGET_INIT_PROC_NAME "on_widget_init" +#define PLUGIN_WIDGET_STOP_PROC_NAME "on_widget_stop" +#define PLUGIN_FRAME_LOAD_PROC_NAME "on_frame_load" +#define PLUGIN_FRAME_UNLOAD_PROC_NAME "on_frame_unload" +#define PLUGIN_CLASS_MAP_NAME "class_map" +#define PLUGIN_GET_CLASS_MAP_PROC_NAME "get_widget_class_map" + +/** + * Plugin export typedefs + */ +typedef void (*on_widget_start_proc)(int widgetId); + +typedef void (*on_widget_init_proc)(feature_mapping_interface_t *interface); + +/** + * FIXME: Add documentation + */ +typedef void (*on_widget_stop_proc)(int widgetId); + +typedef void (*on_frame_load_proc)(java_script_context_t context); + +typedef void (*on_frame_unload_proc)(java_script_context_t context); + +typedef const js_entity_definition_t* (*get_widget_entity_map_proc)(); + +#endif // WRT_PLUGIN_EXPORT_H diff --git a/modules/test/config.cmake b/modules/test/config.cmake new file mode 100644 index 0000000..8310c3c --- /dev/null +++ b/modules/test/config.cmake @@ -0,0 +1,54 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_TEST_ENGINE_SOURCES + ${PROJECT_SOURCE_DIR}/modules/test/src/test_results_collector.cpp + ${PROJECT_SOURCE_DIR}/modules/test/src/test_runner.cpp + ${PROJECT_SOURCE_DIR}/modules/test/src/test_runner_child.cpp + ${PROJECT_SOURCE_DIR}/modules/test/src/test_runner_multiprocess.cpp + ${PROJECT_SOURCE_DIR}/modules/test/src/process_pipe.cpp + ${PROJECT_SOURCE_DIR}/modules/test/src/value_separated_policies.cpp + ${PROJECT_SOURCE_DIR}/modules/test/src/value_separated_tokens.cpp + PARENT_SCOPE +) + + +SET(DPL_TEST_ENGINE_HEADERS + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/test_results_collector.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/test_runner.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/test_runner_child.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/test_runner_multiprocess.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/process_pipe.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/abstract_input_parser.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/abstract_input_reader.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/abstract_input_tokenizer.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/value_separated_parser.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/value_separated_policies.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/value_separated_reader.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/value_separated_tokenizer.h + ${PROJECT_SOURCE_DIR}/modules/test/include/dpl/test/value_separated_tokens.h + PARENT_SCOPE +) + +SET(DPL_TEST_ENGINE_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/test/include + PARENT_SCOPE +) diff --git a/modules/test/include/dpl/test/abstract_input_parser.h b/modules/test/include/dpl/test/abstract_input_parser.h new file mode 100644 index 0000000..dcb2243 --- /dev/null +++ b/modules/test/include/dpl/test/abstract_input_parser.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_input_parser.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Simple parser abstraction to be included into reader + */ + +#ifndef ABSTRACT_INPUT_PARSER_H +#define ABSTRACT_INPUT_PARSER_H + +#include + +#include + +namespace DPL { + +/** + * Abstract class of parser that produces some higher level abstraction + * basing on incoming tokens + */ +template class AbstractInputParser +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, ParserError) + }; + + typedef Result ResultType; + typedef Token TokenType; + + virtual ~AbstractInputParser() {} + + virtual void ConsumeToken(std::unique_ptr && token) = 0; + virtual bool IsStateValid() = 0; + virtual Result GetResult() const = 0; +}; + +} + +#endif diff --git a/modules/test/include/dpl/test/abstract_input_reader.h b/modules/test/include/dpl/test/abstract_input_reader.h new file mode 100644 index 0000000..6b23dd6 --- /dev/null +++ b/modules/test/include/dpl/test/abstract_input_reader.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_input_reader.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Simple output reader template + * + * This generic skeleton for parser which assume being composed from abstract two logical components: + * + * - parser, + * - tokenizer/lexer, + * which implements token flow logic. Logic of components may be arbitrary. See depending change for uses. + * + * Components are created at start time of reader (constructor which moves arguments). + * Virtuality (abstract base classes) are for enforcing same token type. + * I assumed it's more clear than writen static asserts in code enforcing this. + */ + +#ifndef ABSTRACT_INPUT_READER_H +#define ABSTRACT_INPUT_READER_H + +#include + +#include +#include +#include +#include + +namespace DPL { + +/** + * Base reader class that can be used with any AbstractInput instance + * + * This class is encapsulation class for tokenizer and reader subelements + * and contains basic calculation pattern + * + * There a waste in form of virtuality for parser and tokenizer + * -> this for forcing same tokenT type in both components + */ +template class AbstractInputReader +{ +public: + typedef ResultT TokenType; + typedef TokenT ResultType; + typedef AbstractInputParser ParserBase; + typedef AbstractInputTokenizer TokenizerBase; + + class Exception + { + public: + typedef typename TokenizerBase::Exception::TokenizerError TokenizerError; + typedef typename ParserBase::Exception::ParserError ParserError; + }; + + AbstractInputReader(std::shared_ptr ia, + std::unique_ptr && parser, + std::unique_ptr && tokenizer) + : m_parser(std::move(parser)), m_tokenizer(std::move(tokenizer)) + { + m_tokenizer->Reset(ia); + } + + virtual ~AbstractInputReader() {} + + ResultT ReadInput() + { + typedef typename Exception::TokenizerError TokenizerError; + typedef typename Exception::ParserError ParserError; + + while(true) + { + std::unique_ptr token = m_tokenizer->GetNextToken(); + if(!token) + { + if(!m_tokenizer->IsStateValid()) + { + ThrowMsg(TokenizerError, "Tokenizer error"); + } + if(!m_parser->IsStateValid()) + { + ThrowMsg(ParserError, "Parser error"); + } + + return m_parser->GetResult(); + } + m_parser->ConsumeToken(std::move(token)); + } + } + +protected: + std::unique_ptr m_parser; + std::unique_ptr m_tokenizer; +}; + +} + +#endif diff --git a/modules/test/include/dpl/test/abstract_input_tokenizer.h b/modules/test/include/dpl/test/abstract_input_tokenizer.h new file mode 100644 index 0000000..a376341 --- /dev/null +++ b/modules/test/include/dpl/test/abstract_input_tokenizer.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file abstract_input_tokenizer.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Simple tokenizer abstraction + */ + +#ifndef ABSTRACT_INPUT_TOKENIZER_H +#define ABSTRACT_INPUT_TOKENIZER_H + +#include +#include + +#include +#include +#include + +namespace DPL { + +/** + * Tokenizer abstract base class + * + * This class is supposed to accept AbstractInput in constructor + * and produce tokens until end of source. If parsing ends in invalid state + * then IsStateValid() should return false + */ +template class AbstractInputTokenizer +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, TokenizerError) + }; + + typedef Token TokenType; + + AbstractInputTokenizer() {} + virtual ~AbstractInputTokenizer() {} + + /** + * @brief Reset resets data source + * @param wia AbstractWaitableInputAdapter instance + */ + virtual void Reset(std::shared_ptr wia) + { + m_input = wia; + } + + /** + * @brief GetNextToken + * + * Parses next token. + * Returns pointer to token + * @throw TokenizerError in condition of input source error + * If returned empty pointer IsStateValid() == true -> end of input + * IsStateValid() == false -> error + * + * @param token token to be set + * @return + */ + virtual std::unique_ptr GetNextToken() = 0; + virtual bool IsStateValid() = 0; + +protected: + std::shared_ptr m_input; +}; + +} + +#endif diff --git a/modules/test/include/dpl/test/process_pipe.h b/modules/test/include/dpl/test/process_pipe.h new file mode 100644 index 0000000..52ab7e7 --- /dev/null +++ b/modules/test/include/dpl/test/process_pipe.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file process_pipe.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + * @brief This file is the implementation pipe from process + */ +#ifndef PROCESS_PIPE_H +#define PROCESS_PIPE_H + +#include +#include + +#include + +namespace DPL { + +class ProcessPipe : public FileInput +{ +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DoubleOpen) + }; + + enum class PipeErrorPolicy + { + NONE, + OFF, + PIPE + }; + + explicit ProcessPipe(PipeErrorPolicy err = PipeErrorPolicy::NONE); + virtual ~ProcessPipe(); + + void Open(const std::string &command); + void Close(); + +private: + FILE * m_file; + PipeErrorPolicy m_errPolicy; +}; + +} + +#endif // PROCESS_PIPE_H diff --git a/modules/test/include/dpl/test/test_results_collector.h b/modules/test/include/dpl/test/test_results_collector.h new file mode 100644 index 0000000..acb2914 --- /dev/null +++ b/modules/test/include/dpl/test/test_results_collector.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_results_collector.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Header file with declaration of TestResultsCollectorBase + */ + +#ifndef DPL_TEST_RESULTS_COLLECTOR_H +#define DPL_TEST_RESULTS_COLLECTOR_H + +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Test { +class TestResultsCollectorBase; +typedef std::shared_ptr +TestResultsCollectorBasePtr; + +class TestResultsCollectorBase : + private DPL::Noncopyable +{ + public: + typedef TestResultsCollectorBase* (*CollectorConstructorFunc)(); + typedef std::list TestCaseIdList; + struct FailStatus + { + enum Type + { + NONE, + FAILED, + IGNORED, + INTERNAL + }; + }; + + virtual ~TestResultsCollectorBase() {} + + virtual bool Configure() + { + return true; + } + virtual void Start(int count) { DPL_UNUSED_PARAM(count); } + virtual void Finish() { } + virtual void CollectCurrentTestGroupName(const std::string& /*groupName*/) + {} + + virtual void CollectTestsCasesList(const TestCaseIdList& /*list*/) {} + virtual void CollectResult(const std::string& id, + const std::string& description, + const FailStatus::Type status = FailStatus::NONE, + const std::string& reason = "") = 0; + virtual std::string CollectorSpecificHelp() const + { + return ""; + } + virtual bool ParseCollectorSpecificArg (const std::string& /*arg*/) + { + return false; + } + + static TestResultsCollectorBase* Create(const std::string& name); + static void RegisterCollectorConstructor( + const std::string& name, + CollectorConstructorFunc + constructor); + static std::vector GetCollectorsNames(); + + private: + typedef std::map ConstructorsMap; + static ConstructorsMap m_constructorsMap; +}; +} +} + +#endif /* DPL_TEST_RESULTS_COLLECTOR_H */ diff --git a/modules/test/include/dpl/test/test_runner.h b/modules/test/include/dpl/test/test_runner.h new file mode 100644 index 0000000..6cd948f --- /dev/null +++ b/modules/test/include/dpl/test/test_runner.h @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_runner.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the header file of test runner + */ +#ifndef DPL_TEST_RUNNER_H +#define DPL_TEST_RUNNER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DPL { +namespace Test { +class TestRunner +{ + typedef std::map + TestResultsCollectors; + TestResultsCollectors m_collectors; + + std::string m_startTestId; + bool m_runIgnored; + + public: + TestRunner() : + m_terminate(false) + , m_allowChildLogs(false) + {} + + typedef void (*TestCase)(); + + private: + struct TestCaseStruct + { + std::string name; + TestCase proc; + + bool operator <(const TestCaseStruct &other) const + { + return name < other.name; + } + + bool operator ==(const TestCaseStruct &other) const + { + return name == other.name; + } + + TestCaseStruct(const std::string &n, TestCase p) : + name(n), + proc(p) + {} + }; + + typedef std::list TestCaseStructList; + typedef std::map TestCaseGroupMap; + TestCaseGroupMap m_testGroups; + + typedef std::set SelectedTestNameSet; + SelectedTestNameSet m_selectedTestNamesSet; + typedef std::set SelectedTestGroupSet; + SelectedTestGroupSet m_selectedTestGroupSet; + std::string m_currentGroup; + + DPL::Atomic m_totalAssertions; + + // Terminate without any logs. + // Some test requires to call fork function. + // Child process must not produce any logs and should die quietly. + bool m_terminate; + bool m_allowChildLogs; + + void Banner(); + void InvalidArgs(const std::string& message = "Invalid arguments!"); + void Usage(); + + bool filterGroupsByXmls(const std::vector & files); + bool filterByXML(std::map & casesMap); + void normalizeXMLTag(std::string& str, const std::string& testcase); + + enum Status { FAILED, IGNORED, PASS }; + + Status RunTestCase(const TestCaseStruct& testCase); + + void RunTests(); + + void CollectResult(const std::string& id, + const std::string& description, + const TestResultsCollectorBase::FailStatus::Type status + = TestResultsCollectorBase::FailStatus::NONE, + const std::string& reason = std::string()); + + public: + class TestFailed + { + private: + std::string m_message; + + public: + TestFailed() + {} + + //! \brief Failed test message creator + //! + //! \param[in] aTest string for tested expression + //! \param[in] aFile source file name + //! \param[in] aLine source file line + //! \param[in] aMessage error message + TestFailed(const char* aTest, + const char* aFile, + int aLine, + const std::string &aMessage); + + TestFailed(const std::string &message); + + std::string GetMessage() const + { + return m_message; + } + }; + + class Ignored + { + private: + std::string m_message; + + public: + Ignored() + {} + + Ignored(const std::string &message) : + m_message(message) + {} + + std::string GetMessage() const + { + return m_message; + } + }; + + void MarkAssertion(); + + void RegisterTest(const char *testName, TestCase proc); + void InitGroup(const char* name); + + int ExecTestRunner(int argc, char *argv[]); + typedef std::vector ArgsList; + int ExecTestRunner(const ArgsList& args); + bool getRunIgnored() const; + // The runner will terminate as soon as possible (after current test). + void Terminate(); + bool GetAllowChildLogs(); +}; + +typedef DPL::Singleton TestRunnerSingleton; +} +} // namespace DPL + +#define RUNNER_TEST_GROUP_INIT(GroupName) \ + static int Static##GroupName##Init() \ + { \ + DPL::Test::TestRunnerSingleton::Instance().InitGroup(#GroupName); \ + return 0; \ + } \ + const int DPL_UNUSED Static##GroupName##InitVar = \ + Static##GroupName##Init(); + +#define RUNNER_TEST(Proc) \ + void Proc(); \ + static int Static##Proc##Init() \ + { \ + DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \ + return 0; \ + } \ + const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init(); \ + void Proc() + +//! \brief Returns base name for path + +#define RUNNER_ASSERT_MSG(test, message) \ + do \ + { \ + DPL::Test::TestRunnerSingleton::Instance().MarkAssertion(); \ + \ + if (!(test)) \ + { \ + std::ostringstream assertMsg; \ + assertMsg << message; \ + throw DPL::Test::TestRunner::TestFailed(#test, \ + __FILE__, \ + __LINE__, \ + assertMsg.str()); \ + } \ + } while (0) + +#define RUNNER_ASSERT(test) RUNNER_ASSERT_MSG(test, "") + +#define RUNNER_FAIL RUNNER_ASSERT(false) + +#define RUNNER_IGNORED_MSG(message) do { std::ostringstream assertMsg; \ + assertMsg << message; \ + throw DPL::Test::TestRunner::Ignored( \ + assertMsg.str()); \ +} while (0) + +#endif // DPL_TEST_RUNNER_H diff --git a/modules/test/include/dpl/test/test_runner_child.h b/modules/test/include/dpl/test/test_runner_child.h new file mode 100644 index 0000000..1da0f1b --- /dev/null +++ b/modules/test/include/dpl/test/test_runner_child.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_runner_child.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief This file is the header file of test runner + */ +#ifndef DPL_TEST_RUNNER_CHILD_H +#define DPL_TEST_RUNNER_CHILD_H + +#include + +namespace DPL { +namespace Test { + +class PipeWrapper : DPL::Noncopyable +{ + public: + enum Usage { + READONLY, + WRITEONLY + }; + + enum Status { + SUCCESS, + TIMEOUT, + ERROR + }; + + PipeWrapper(); + + bool isReady(); + + void setUsage(Usage usage); + + virtual ~PipeWrapper(); + + Status send(int code, std::string &message); + + Status receive(int &code, std::string &data, time_t deadline); + + void closeAll(); + + protected: + + std::string toBinaryString(int data); + + void closeHelp(int desc); + + Status writeHelp(const void *buffer, int size); + + Status readHelp(void *buf, int size, time_t deadline); + + static const int PIPE_CLOSED = -1; + + int m_pipefd[2]; +}; + +void RunChildProc(TestRunner::TestCase procChild); +} // namespace Test +} // namespace DPL + +#define RUNNER_CHILD_TEST(Proc) \ + void Proc(); \ + void Proc##Child(); \ + static int Static##Proc##Init() \ + { \ + DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \ + return 0; \ + } \ + const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init(); \ + void Proc(){ \ + DPL::Test::RunChildProc(&Proc##Child); \ + } \ + void Proc##Child() + +#endif // DPL_TEST_RUNNER_CHILD_H diff --git a/modules/test/include/dpl/test/test_runner_multiprocess.h b/modules/test/include/dpl/test/test_runner_multiprocess.h new file mode 100644 index 0000000..279b5ef --- /dev/null +++ b/modules/test/include/dpl/test/test_runner_multiprocess.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_runner_multiprocess.h + * @author Marcin Niesluchowski (m.niesluchow@samsung.com) + * @version 1.0 + * @brief This file is the header file of multiprocess test runner + */ +#ifndef DPL_TEST_RUNNER_MULTIPROCESS_H +#define DPL_TEST_RUNNER_MULTIPROCESS_H + +#include + +namespace DPL { +namespace Test { + +class SimplePipeWrapper : + public PipeWrapper +{ + public: + SimplePipeWrapper(); + + virtual ~SimplePipeWrapper(); + + Status send(std::string &message); + Status receive(std::string &data, bool &empty, time_t deadline); +}; + +void RunMultiProc(TestRunner::TestCase procMulti); +} // namespace Test +} // namespace DPL + +#define RUNNER_MULTIPROCESS_TEST(Proc) \ + void Proc(); \ + void Proc##Multi(); \ + static int Static##Proc##Init() \ + { \ + DPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \ + return 0; \ + } \ + const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init(); \ + void Proc(){ \ + DPL::Test::RunMultiProc(&Proc##Multi); \ + } \ + void Proc##Multi() + +#endif // DPL_TEST_RUNNER_MULTIPROCESS_H diff --git a/modules/test/include/dpl/test/value_separated_parser.h b/modules/test/include/dpl/test/value_separated_parser.h new file mode 100644 index 0000000..635e548 --- /dev/null +++ b/modules/test/include/dpl/test/value_separated_parser.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file value_separated_parser.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Parser for some value seperated files/data + */ + +#ifndef VALUE_SEPARATED_PARSER_H +#define VALUE_SEPARATED_PARSER_H + +#include +#include +#include + +#include +#include + +namespace DPL { + +typedef std::vector VSLine; +typedef std::vector VSResult; +typedef std::shared_ptr VSResultPtr; + +/** + * Value Seperated parser + * + * Requires following policy class: + * + * template + * struct CSVParserPolicy + * { + * static bool SkipLine(VSLine & ); + * static bool Validate(VSResultPtr& result); + * }; + */ +template +class VSParser : public AbstractInputParser +{ +public: + VSParser() : m_switchLine(true), m_result(new VSResult()) {} + + void ConsumeToken(std::unique_ptr && token) + { + if(m_switchLine) + { + m_result->push_back(VSLine()); + m_switchLine = false; + } + if(token->isNewLine()) + { + if(ParserPolicy::SkipLine(*m_result->rbegin())) + { + m_result->pop_back(); + } + m_switchLine = true; + } + else + { + m_result->rbegin()->push_back(token->cell()); + } + } + + bool IsStateValid() + { + return ParserPolicy::Validate(m_result); + } + + VSResultPtr GetResult() const + { + return m_result; + } + +private: + bool m_switchLine; + VSResultPtr m_result; +}; + +} + +#endif diff --git a/modules/test/include/dpl/test/value_separated_policies.h b/modules/test/include/dpl/test/value_separated_policies.h new file mode 100644 index 0000000..c432703 --- /dev/null +++ b/modules/test/include/dpl/test/value_separated_policies.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file value_separated_policies.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Example policy classes for some value seperated files/data + */ + +#ifndef VALUE_SEPARATED_POLICIES_H +#define VALUE_SEPARATED_POLICIES_H + +#include +#include +#include + +namespace DPL { + +struct CSVTokenizerPolicy +{ + static std::string GetSeperators(); //cells in line are separated by given characters + static bool SkipEmpty(); //if cell is empty, shoudl I skip? + static void PrepareValue(std::string &); //transform each value + static bool TryAgainAtEnd(int); //read is nonblocking so dat may not be yet available, should I retry? +}; + +struct CSVParserPolicy +{ + static bool SkipLine(const std::vector & ); //should I skip whole readline? + static bool Validate(std::shared_ptr > > & result); //validate and adjust output data +}; + +} + +#endif diff --git a/modules/test/include/dpl/test/value_separated_reader.h b/modules/test/include/dpl/test/value_separated_reader.h new file mode 100644 index 0000000..8e78aaa --- /dev/null +++ b/modules/test/include/dpl/test/value_separated_reader.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file value_separated_reader.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Reader for some value seperated files/data + * + * This is parser for files containing lines with values seperated with custom charaters. + * Purpose of this is to parse output similar to csv and hide (no need for rewriting) + * buffers, reads, code errors. Result is two dimensional array. + * + * Reader is designed as class configured with policies classes: + * http://en.wikipedia.org/wiki/Policy-based_design + */ + +#ifndef VALUE_SEPARATED_READER_H +#define VALUE_SEPARATED_READER_H + +#include +#include +#include +#include +#include + +namespace DPL { + +/** + * Reader for input with values separated with defined characters + * + * Usage: + * - define both policies classes for defining and customize exact behaviour of reader + * - make typedef for VSReader template instance with your policies + * + */ +template +class VSReader : public AbstractInputReader +{ +public: + VSReader(std::shared_ptr wia) + : AbstractInputReader(wia, + std::unique_ptr(new VSParser()), + std::unique_ptr(new VSTokenizer())) + {} +}; + +typedef VSReader CSVReader; + +} + +#endif diff --git a/modules/test/include/dpl/test/value_separated_tokenizer.h b/modules/test/include/dpl/test/value_separated_tokenizer.h new file mode 100644 index 0000000..13403b5 --- /dev/null +++ b/modules/test/include/dpl/test/value_separated_tokenizer.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file value_separated_tokenizer.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Tokenizer for some value seperated files/data + */ + +#ifndef VALUE_SEPARATED_TOKENIZER_H +#define VALUE_SEPARATED_TOKENIZER_H + +#include +#include +#include + + +namespace DPL { + +/** + * Value Sperated tokenizer + * + * Requires following policy class: + * + * struct TokenizerPolicy + * { + * static std::string GetSeperators(); + * static bool SkipEmpty(); + * static void PrepareValue(std::string & value); + * }; + */ +template +class VSTokenizer : public AbstractInputTokenizer +{ +public: + VSTokenizer() {} + + void Reset(std::shared_ptr ia) + { + AbstractInputTokenizer::Reset(ia); + m_queue.Clear(); + m_finished = false; + m_newline = false; + } + + std::unique_ptr GetNextToken() + { + std::unique_ptr token; + std::string data; + char byte; + int tryNumber = 0; + + while(true) + { + //check if newline was approched + if(m_newline) + { + token.reset(new VSToken()); + m_newline = false; + return token; + } + + //read next data + if(m_queue.Empty()) + { + if(m_finished) + { + return token; + } + else + { + auto baptr = m_input->Read(4096); + if(baptr.get() == 0) + { + ThrowMsg(Exception::TokenizerError, "Input read failed"); + } + if(baptr->Empty()) + { + if(TokenizerPolicy::TryAgainAtEnd(tryNumber)) + { + ++tryNumber; + continue; + } + m_finished = true; + return token; + } + m_queue.AppendMoveFrom(*baptr); + } + } + + //process + m_queue.FlattenConsume(&byte, 1); //queue uses pointer to consume bytes, this do not causes reallocations + if(byte == '\n') + { + m_newline = true; + if(!data.empty() || !TokenizerPolicy::SkipEmpty()) + { + ProduceString(token, data); + return token; + } + } + else if(TokenizerPolicy::GetSeperators().find(byte) != std::string::npos) + { + if(!data.empty() || !TokenizerPolicy::SkipEmpty()) + { + ProduceString(token, data); + return token; + } + } + else + { + data += byte; + } + } + } + + bool IsStateValid() + { + if(!m_queue.Empty() && m_finished) return false; + return true; + } + +protected: + void ProduceString(std::unique_ptr & token, std::string & data) + { + TokenizerPolicy::PrepareValue(data); + token.reset(new VSToken(data)); + } + + BinaryQueue m_queue; + bool m_finished; + bool m_newline; +}; + +} + +#endif diff --git a/modules/test/include/dpl/test/value_separated_tokens.h b/modules/test/include/dpl/test/value_separated_tokens.h new file mode 100644 index 0000000..3c49157 --- /dev/null +++ b/modules/test/include/dpl/test/value_separated_tokens.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file value_separated_tokens.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief Token class for some value seperated files/data + */ + +#ifndef VALUE_SEPARATED_TOKENS_H +#define VALUE_SEPARATED_TOKENS_H + +#include + +namespace DPL { + +class VSToken +{ +public: + VSToken(const std::string & c); + VSToken(); //newline token - no new class to simplify + const std::string & cell() const; + + bool isNewLine(); +private: + bool m_newline; + std::string m_cell; +}; + +} + +#endif diff --git a/modules/test/src/process_pipe.cpp b/modules/test/src/process_pipe.cpp new file mode 100644 index 0000000..68c910f --- /dev/null +++ b/modules/test/src/process_pipe.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file process_pipe.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + * @brief This file is the implementation pipe from process + */ + +#include +#include + +namespace DPL { + +ProcessPipe::ProcessPipe(PipeErrorPolicy err) : m_file(NULL), m_errPolicy(err) +{ +} + +ProcessPipe::~ProcessPipe() +{ +} + +void ProcessPipe::Open(const std::string & command) +{ + if(m_file != NULL) + { + ThrowMsg(Exception::DoubleOpen, "Trying to open pipe second time. Close it first"); + } + + std::string stdErrRedirection; + switch(m_errPolicy) + { + case PipeErrorPolicy::NONE: break; + case PipeErrorPolicy::OFF: stdErrRedirection = " 2>/dev/null"; break; + case PipeErrorPolicy::PIPE: stdErrRedirection = " 2>&1"; break; + default: break; + } + + std::string fcommand = command + stdErrRedirection; + FILE * file = popen(fcommand.c_str(), "r"); + + // Throw an exception if an error occurred + if (file == NULL) { + ThrowMsg(FileInput::Exception::OpenFailed, fcommand); + } + + // Save new descriptor + m_file = file; + m_fd = fileno(m_file); + + LogPedantic("Opened pipe: " << fcommand); +} + +void ProcessPipe::Close() +{ + if (m_fd == -1) { + return; + } + + if (pclose(m_file) == -1) { + Throw(FileInput::Exception::CloseFailed); + } + + m_fd = -1; + m_file = NULL; + + LogPedantic("Closed pipe"); +} + +} diff --git a/modules/test/src/test_results_collector.cpp b/modules/test/src/test_results_collector.cpp new file mode 100644 index 0000000..665ca7d --- /dev/null +++ b/modules/test/src/test_results_collector.cpp @@ -0,0 +1,987 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_results_collector.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Implementation file some concrete TestResulstsCollector + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define GREEN_RESULT_OK "[%s%s%s]\n", BOLD_GREEN_BEGIN, " OK ", \ + BOLD_GREEN_END + +namespace DPL { +namespace Test { +namespace { +const char *DEFAULT_HTML_FILE_NAME = "index.html"; +const char *DEFAULT_TAP_FILE_NAME = "results.tap"; +const char *DEFAULT_XML_FILE_NAME = "results.xml"; + +bool ParseCollectorFileArg(const std::string &arg, std::string &filename) +{ + const std::string argname = "--file="; + if (arg.find(argname) == 0 ) { + filename = arg.substr(argname.size()); + return true; + } + return false; +} + +class Statistic +{ + public: + Statistic() : + m_failed(0), + m_ignored(0), + m_passed(0), + m_count(0) + {} + + void AddTest(TestResultsCollectorBase::FailStatus::Type type) + { + ++m_count; + switch (type) { + case TestResultsCollectorBase::FailStatus::INTERNAL: + case TestResultsCollectorBase::FailStatus::FAILED: ++m_failed; + break; + case TestResultsCollectorBase::FailStatus::IGNORED: ++m_ignored; + break; + case TestResultsCollectorBase::FailStatus::NONE: ++m_passed; + break; + default: + Assert(false && "Bad FailStatus"); + } + } + + std::size_t GetTotal() const + { + return m_count; + } + std::size_t GetPassed() const + { + return m_passed; + } + std::size_t GetSuccesed() const + { + return m_passed; + } + std::size_t GetFailed() const + { + return m_failed; + } + std::size_t GetIgnored() const + { + return m_ignored; + } + float GetPassedOrIgnoredPercend() const + { + float passIgnoredPercent = + 100.0f * (static_cast(m_passed) + + static_cast(m_ignored)) + / static_cast(m_count); + return passIgnoredPercent; + } + + private: + std::size_t m_failed; + std::size_t m_ignored; + std::size_t m_passed; + std::size_t m_count; +}; + +class ConsoleCollector : + public TestResultsCollectorBase +{ + public: + static TestResultsCollectorBase* Constructor(); + + private: + ConsoleCollector() {} + + virtual void CollectCurrentTestGroupName(const std::string& name) + { + printf("Starting group %s\n", name.c_str()); + m_currentGroup = name; + } + + virtual void Finish() + { + using namespace DPL::Colors::Text; + + // Show result + FOREACH(group, m_groupsStats) { + PrintStats(group->first, group->second); + } + PrintStats("All tests together", m_stats); + } + + virtual void CollectResult(const std::string& id, + const std::string& /*description*/, + const FailStatus::Type status = FailStatus::NONE, + const std::string& reason = "") + { + using namespace DPL::Colors::Text; + std::string tmp = "'" + id + "' ..."; + + printf("Running test case %-60s", tmp.c_str()); + switch (status) { + case TestResultsCollectorBase::FailStatus::NONE: + printf(GREEN_RESULT_OK); + break; + case TestResultsCollectorBase::FailStatus::FAILED: + PrintfErrorMessage(" FAILED ", reason, true); + break; + case TestResultsCollectorBase::FailStatus::IGNORED: + PrintfIgnoredMessage("Ignored ", reason, true); + break; + case TestResultsCollectorBase::FailStatus::INTERNAL: + PrintfErrorMessage("INTERNAL", reason, true); + break; + default: + Assert(false && "Bad status"); + } + m_stats.AddTest(status); + m_groupsStats[m_currentGroup].AddTest(status); + } + + void PrintfErrorMessage(const char* type, + const std::string& message, + bool verbosity) + { + using namespace DPL::Colors::Text; + if (verbosity) { + printf("[%s%s%s] %s%s%s\n", + BOLD_RED_BEGIN, + type, + BOLD_RED_END, + BOLD_YELLOW_BEGIN, + message.c_str(), + BOLD_YELLOW_END); + } else { + printf("[%s%s%s]\n", + BOLD_RED_BEGIN, + type, + BOLD_RED_END); + } + } + + void PrintfIgnoredMessage(const char* type, + const std::string& message, + bool verbosity) + { + using namespace DPL::Colors::Text; + if (verbosity) { + printf("[%s%s%s] %s%s%s\n", + CYAN_BEGIN, + type, + CYAN_END, + BOLD_GOLD_BEGIN, + message.c_str(), + BOLD_GOLD_END); + } else { + printf("[%s%s%s]\n", + CYAN_BEGIN, + type, + CYAN_END); + } + } + + void PrintStats(const std::string& title, const Statistic& stats) + { + using namespace DPL::Colors::Text; + printf("\n%sResults [%s]: %s\n", BOLD_GREEN_BEGIN, + title.c_str(), BOLD_GREEN_END); + printf("%s%s%3d%s\n", + CYAN_BEGIN, + "Total tests: ", + stats.GetTotal(), + CYAN_END); + printf(" %s%s%3d%s\n", + CYAN_BEGIN, + "Succeeded: ", + stats.GetPassed(), + CYAN_END); + printf(" %s%s%3d%s\n", + CYAN_BEGIN, + "Failed: ", + stats.GetFailed(), + CYAN_END); + printf(" %s%s%3d%s\n", + CYAN_BEGIN, + "Ignored: ", + stats.GetIgnored(), + CYAN_END); + } + + Statistic m_stats; + std::map m_groupsStats; + std::string m_currentGroup; +}; + +TestResultsCollectorBase* ConsoleCollector::Constructor() +{ + return new ConsoleCollector(); +} + +class HtmlCollector : + public TestResultsCollectorBase +{ + public: + static TestResultsCollectorBase* Constructor(); + + private: + HtmlCollector() : m_filename(DEFAULT_HTML_FILE_NAME) {} + + virtual void CollectCurrentTestGroupName(const std::string& name) + { + fprintf(m_fp.Get(), "Starting group %s", name.c_str()); + m_currentGroup = name; + } + + virtual bool Configure() + { + m_fp.Reset(fopen(m_filename.c_str(), "w")); + if (!m_fp) { + LogPedantic("Could not open file " << m_filename << " for writing"); + return false; + } + return true; + } + virtual std::string CollectorSpecificHelp() const + { + return "--file= - name of file for output\n" + " default - index.html\n"; + } + + virtual void Start(int count) + { + DPL_UNUSED_PARAM(count); + AssertMsg(!!m_fp, "File handle must not be null"); + fprintf(m_fp.Get(), + "\n"); + fprintf(m_fp.Get(), + "\n"); + fprintf(m_fp.Get(), "\n"); + fprintf(m_fp.Get(), "
\n");
+        fprintf(m_fp.Get(), "\n");
+    }
+
+    virtual void Finish()
+    {
+        using namespace DPL::Colors::Html;
+        // Show result
+        FOREACH(group, m_groupsStats) {
+            PrintStats(group->first, group->second);
+        }
+        PrintStats("All tests together", m_stats);
+        fprintf(m_fp.Get(), "\n");
+        fprintf(m_fp.Get(), "
\n"); + fprintf(m_fp.Get(), "\n"); + fprintf(m_fp.Get(), "\n"); + } + + virtual bool ParseCollectorSpecificArg(const std::string& arg) + { + return ParseCollectorFileArg(arg, m_filename); + } + + virtual void CollectResult(const std::string& id, + const std::string& /*description*/, + const FailStatus::Type status = FailStatus::NONE, + const std::string& reason = "") + { + using namespace DPL::Colors::Html; + std::string tmp = "'" + id + "' ..."; + + fprintf(m_fp.Get(), "Running test case %-100s", tmp.c_str()); + switch (status) { + case TestResultsCollectorBase::FailStatus::NONE: + fprintf(m_fp.Get(), GREEN_RESULT_OK); + break; + case TestResultsCollectorBase::FailStatus::FAILED: + PrintfErrorMessage(" FAILED ", reason, true); + break; + case TestResultsCollectorBase::FailStatus::IGNORED: + PrintfIgnoredMessage("Ignored ", reason, true); + break; + case TestResultsCollectorBase::FailStatus::INTERNAL: + PrintfErrorMessage("INTERNAL", reason, true); + break; + default: + Assert(false && "Bad status"); + } + m_groupsStats[m_currentGroup].AddTest(status); + m_stats.AddTest(status); + } + + void PrintfErrorMessage(const char* type, + const std::string& message, + bool verbosity) + { + using namespace DPL::Colors::Html; + if (verbosity) { + fprintf(m_fp.Get(), + "[%s%s%s] %s%s%s\n", + BOLD_RED_BEGIN, + type, + BOLD_RED_END, + BOLD_YELLOW_BEGIN, + message.c_str(), + BOLD_YELLOW_END); + } else { + fprintf(m_fp.Get(), + "[%s%s%s]\n", + BOLD_RED_BEGIN, + type, + BOLD_RED_END); + } + } + + void PrintfIgnoredMessage(const char* type, + const std::string& message, + bool verbosity) + { + using namespace DPL::Colors::Html; + + if (verbosity) { + fprintf(m_fp.Get(), + "[%s%s%s] %s%s%s\n", + CYAN_BEGIN, + type, + CYAN_END, + BOLD_GOLD_BEGIN, + message.c_str(), + BOLD_GOLD_END); + } else { + fprintf(m_fp.Get(), + "[%s%s%s]\n", + CYAN_BEGIN, + type, + CYAN_END); + } + } + + void PrintStats(const std::string& name, const Statistic& stats) + { + using namespace DPL::Colors::Html; + fprintf( + m_fp.Get(), "\n%sResults [%s]:%s\n", BOLD_GREEN_BEGIN, + name.c_str(), BOLD_GREEN_END); + fprintf( + m_fp.Get(), "%s%s%3d%s\n", CYAN_BEGIN, + "Total tests: ", stats.GetTotal(), CYAN_END); + fprintf( + m_fp.Get(), " %s%s%3d%s\n", CYAN_BEGIN, + "Succeeded: ", stats.GetPassed(), CYAN_END); + fprintf( + m_fp.Get(), " %s%s%3d%s\n", CYAN_BEGIN, + "Failed: ", stats.GetFailed(), CYAN_END); + fprintf( + m_fp.Get(), " %s%s%3d%s\n", CYAN_BEGIN, + "Ignored: ", stats.GetIgnored(), CYAN_END); + } + + std::string m_filename; + ScopedFClose m_fp; + Statistic m_stats; + std::string m_currentGroup; + std::map m_groupsStats; +}; + +TestResultsCollectorBase* HtmlCollector::Constructor() +{ + return new HtmlCollector(); +} + +class XmlCollector : + public TestResultsCollectorBase +{ + public: + static TestResultsCollectorBase* Constructor(); + + private: + XmlCollector() : m_filename(DEFAULT_XML_FILE_NAME) {} + + virtual void CollectCurrentTestGroupName(const std::string& name) + { + std::size_t pos = GetCurrentGroupPosition(); + if (std::string::npos != pos) { + GroupFinish(pos); + FlushOutput(); + m_stats = Statistic(); + } + + pos = m_outputBuffer.find(""); + if (std::string::npos == pos) { + ThrowMsg(DPL::Exception, "Could not find test suites closing tag"); + } + GroupStart(pos, name); + } + + void GroupStart(const std::size_t pos, const std::string& name) + { + std::stringstream groupHeader; + groupHeader << "\n\t"; + + groupHeader << "\n\t\t"; + groupHeader << + "\n\t\t\t"; + groupHeader << "\n\t\t"; + + groupHeader << "\n\t"; + + m_outputBuffer.insert(pos - 1, groupHeader.str()); + } + + virtual bool Configure() + { + m_fp.Reset(fopen(m_filename.c_str(), "w")); + if (!m_fp) { + LogPedantic("Could not open file " << m_filename << " for writing"); + return false; + } + return true; + } + + virtual std::string CollectorSpecificHelp() const + { + return "--file= - name of file for output\n" + " default - results.xml\n"; + } + + virtual void Start(int count) + { + AssertMsg(!!m_fp, "File handle must not be null"); + m_outputBuffer.append("\n"); + m_outputBuffer.append("= 0) + { + m_outputBuffer.append("total=\""); + m_outputBuffer.append(DPL::lexical_cast(count)); + m_outputBuffer.append("\""); + } + m_outputBuffer.append(" >\n"); + FlushOutput(); + } + + virtual void Finish() + { + std::size_t pos = GetCurrentGroupPosition(); + if (std::string::npos != pos) { + GroupFinish(pos); + FlushOutput(); + } + } + + virtual bool ParseCollectorSpecificArg(const std::string& arg) + { + return ParseCollectorFileArg(arg, m_filename); + } + + virtual void CollectResult(const std::string& id, + const std::string& /*description*/, + const FailStatus::Type status = FailStatus::NONE, + const std::string& reason = "") + { + m_resultBuffer.erase(); + m_resultBuffer.append("\t\t\n"); + break; + case TestResultsCollectorBase::FailStatus::FAILED: + m_resultBuffer.append(" status=\"FAILED\">\n"); + PrintfErrorMessage("FAILED", EscapeSpecialCharacters(reason), true); + m_resultBuffer.append("\t\t\n"); + break; + case TestResultsCollectorBase::FailStatus::IGNORED: + m_resultBuffer.append(" status=\"Ignored\">\n"); + PrintfIgnoredMessage("Ignored", EscapeSpecialCharacters( + reason), true); + m_resultBuffer.append("\t\t\n"); + break; + case TestResultsCollectorBase::FailStatus::INTERNAL: + m_resultBuffer.append(" status=\"FAILED\">\n"); + PrintfErrorMessage("INTERNAL", EscapeSpecialCharacters( + reason), true); + m_resultBuffer.append("\t\t"); + break; + default: + Assert(false && "Bad status"); + } + std::size_t group_pos = GetCurrentGroupPosition(); + if (std::string::npos == group_pos) { + ThrowMsg(DPL::Exception, "No current group set"); + } + + std::size_t last_case_pos = m_outputBuffer.find( + "\n"); + } else { + m_resultBuffer.append("\t\t\t\n"); + } + } + + void PrintfIgnoredMessage(const char* type, + const std::string& message, + bool verbosity) + { + if (verbosity) { + m_resultBuffer.append("\t\t\t\n"); + } else { + m_resultBuffer.append("\t\t\t\n"); + } + } + + std::string EscapeSpecialCharacters(std::string s) + { + for (unsigned int i = 0; i < s.size();) { + switch (s[i]) { + case '"': + s.erase(i, 1); + s.insert(i, """); + i += 6; + break; + + case '&': + s.erase(i, 1); + s.insert(i, "&"); + i += 5; + break; + + case '<': + s.erase(i, 1); + s.insert(i, "<"); + i += 4; + break; + + case '>': + s.erase(i, 1); + s.insert(i, ">"); + i += 4; + break; + + case '\'': + s.erase(i, 1); + s.insert(i, "'"); + i += 5; + break; + default: + ++i; + break; + } + } + return s; + } + + std::string m_filename; + ScopedFClose m_fp; + Statistic m_stats; + std::string m_outputBuffer; + std::string m_resultBuffer; +}; + +TestResultsCollectorBase* XmlCollector::Constructor() +{ + return new XmlCollector(); +} + +class CSVCollector : + public TestResultsCollectorBase +{ + public: + static TestResultsCollectorBase* Constructor(); + + private: + CSVCollector() {} + + virtual void Start(int count) + { + DPL_UNUSED_PARAM(count); + printf("GROUP;ID;RESULT;REASON\n"); + } + + virtual void CollectCurrentTestGroupName(const std::string& name) + { + m_currentGroup = name; + } + + virtual void CollectResult(const std::string& id, + const std::string& /*description*/, + const FailStatus::Type status = FailStatus::NONE, + const std::string& reason = "") + { + std::string statusMsg = ""; + switch (status) { + case TestResultsCollectorBase::FailStatus::NONE: statusMsg = "OK"; + break; + case TestResultsCollectorBase::FailStatus::FAILED: statusMsg = "FAILED"; + break; + case TestResultsCollectorBase::FailStatus::IGNORED: statusMsg = + "IGNORED"; + break; + case TestResultsCollectorBase::FailStatus::INTERNAL: statusMsg = + "FAILED"; + break; + default: + Assert(false && "Bad status"); + } + printf("%s;%s;%s;%s\n", + m_currentGroup.c_str(), + id.c_str(), + statusMsg.c_str(), + reason.c_str()); + } + + std::string m_currentGroup; +}; + +TestResultsCollectorBase* CSVCollector::Constructor() +{ + return new CSVCollector(); +} +} + +class TAPCollector : + public TestResultsCollectorBase +{ + public: + static TestResultsCollectorBase* Constructor(); + + private: + TAPCollector() : m_filename(DEFAULT_TAP_FILE_NAME) {} + + virtual bool Configure() + { + m_output.open(m_filename.c_str(), std::ios_base::trunc); + if (m_output.fail()) { + LogError("Can't open output file: " << m_filename); + return false; + } + return true; + } + virtual std::string CollectorSpecificHelp() const + { + std::string retVal = "--file= - name of file for output\n" + " default - "; + retVal += DEFAULT_TAP_FILE_NAME; + retVal += "\n"; + return retVal; + } + + virtual void Start(int count) + { + DPL_UNUSED_PARAM(count); + AssertMsg(m_output.good(), "Output file must be opened."); + m_output << "TAP version 13" << std::endl; + m_testIndex = 0; + } + + virtual void Finish() + { + m_output << "1.." << m_testIndex << std::endl; + m_output << m_collectedData.rdbuf(); + m_output.close(); + } + + virtual bool ParseCollectorSpecificArg(const std::string& arg) + { + return ParseCollectorFileArg(arg, m_filename); + } + + virtual void CollectResult(const std::string& id, + const std::string& description, + const FailStatus::Type status = FailStatus::NONE, + const std::string& reason = "") + { + m_testIndex++; + switch (status) { + case TestResultsCollectorBase::FailStatus::NONE: + LogBasicTAP(true, id, description); + endTAPLine(); + break; + case TestResultsCollectorBase::FailStatus::FAILED: + LogBasicTAP(false, id, description); + endTAPLine(); + break; + case TestResultsCollectorBase::FailStatus::IGNORED: + LogBasicTAP(true, id, description); + m_collectedData << " # skip " << reason; + endTAPLine(); + break; + case TestResultsCollectorBase::FailStatus::INTERNAL: + LogBasicTAP(true, id, description); + endTAPLine(); + m_collectedData << " ---" << std::endl; + m_collectedData << " message: " << reason << std::endl; + m_collectedData << " severity: Internal" << std::endl; + m_collectedData << " ..." << std::endl; + break; + default: + Assert(false && "Bad status"); + } + } + + void LogBasicTAP(bool isOK, const std::string& id, + const std::string& description) + { + if (!isOK) { + m_collectedData << "not "; + } + m_collectedData << "ok " << m_testIndex << " [" << + id << "] " << description; + } + + void endTAPLine() + { + m_collectedData << std::endl; + } + + std::string m_filename; + std::stringstream m_collectedData; + std::ofstream m_output; + int m_testIndex; +}; + +TestResultsCollectorBase* TAPCollector::Constructor() +{ + return new TAPCollector(); +} + +void TestResultsCollectorBase::RegisterCollectorConstructor( + const std::string& name, + TestResultsCollectorBase::CollectorConstructorFunc func) +{ + Assert(m_constructorsMap.find(name) == m_constructorsMap.end()); + m_constructorsMap[name] = func; +} + +TestResultsCollectorBase* TestResultsCollectorBase::Create( + const std::string& name) +{ + ConstructorsMap::iterator found = m_constructorsMap.find(name); + if (found != m_constructorsMap.end()) { + return found->second(); + } else { + return NULL; + } +} + +std::vector TestResultsCollectorBase::GetCollectorsNames() +{ + std::vector list; + FOREACH(it, m_constructorsMap) + { + list.push_back(it->first); + } + return list; +} + +TestResultsCollectorBase::ConstructorsMap TestResultsCollectorBase:: + m_constructorsMap; + +namespace { +static int RegisterCollectorConstructors(); +static const int RegisterHelperVariable = RegisterCollectorConstructors(); +int RegisterCollectorConstructors() +{ + (void)RegisterHelperVariable; + + TestResultsCollectorBase::RegisterCollectorConstructor( + "text", + &ConsoleCollector::Constructor); + TestResultsCollectorBase::RegisterCollectorConstructor( + "html", + &HtmlCollector::Constructor); + TestResultsCollectorBase::RegisterCollectorConstructor( + "csv", + &CSVCollector::Constructor); + TestResultsCollectorBase::RegisterCollectorConstructor( + "tap", + &TAPCollector::Constructor); + TestResultsCollectorBase::RegisterCollectorConstructor( + "xml", + &XmlCollector::Constructor); + + return 0; +} +} +} +} +#undef GREEN_RESULT_OK diff --git a/modules/test/src/test_runner.cpp b/modules/test/src/test_runner.cpp new file mode 100644 index 0000000..aaac7af --- /dev/null +++ b/modules/test/src/test_runner.cpp @@ -0,0 +1,700 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_runner.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test runner + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +IMPLEMENT_SINGLETON(DPL::Test::TestRunner) + +namespace { + +std::string getXMLNode(xmlNodePtr node) +{ + std::string ret; + xmlChar * value = xmlNodeGetContent(node); + ret = std::string(reinterpret_cast(value)); + xmlFree(value); + return ret; +} + +} + + +namespace DPL { +namespace Test { +namespace // anonymous +{ +std::string BaseName(std::string aPath) +{ + ScopedFree path(strdup(aPath.c_str())); + if (NULL == path.Get()) { + throw std::bad_alloc(); + } + char* baseName = basename(path.Get()); + std::string retValue = baseName; + return retValue; +} +} // namespace anonymous + +//! \brief Failed test message creator +//! +//! \param[in] aTest string for tested expression +//! \param[in] aFile source file name +//! \param[in] aLine source file line +//! \param[in] aMessage error message +TestRunner::TestFailed::TestFailed(const char* aTest, + const char* aFile, + int aLine, + const std::string &aMessage) +{ + std::ostringstream assertMsg; + assertMsg << "[" << BaseName(aFile) << ":" << aLine + << "] Assertion failed (" + << aTest << ") " << aMessage; + m_message = assertMsg.str(); +} + +TestRunner::TestFailed::TestFailed(const std::string &message) +{ + m_message = message; +} + +void TestRunner::RegisterTest(const char *testName, TestCase proc) +{ + m_testGroups[m_currentGroup].push_back(TestCaseStruct(testName, proc)); +} + +void TestRunner::InitGroup(const char* name) +{ + m_currentGroup = name; +} + +void TestRunner::normalizeXMLTag(std::string& str, const std::string& testcase) +{ + //Add testcase if missing + std::string::size_type pos = str.find(testcase); + if(pos != 0) + { + str = testcase + "_" + str; + } + + //dpl test runner cannot have '-' character in name so it have to be replaced + // for TCT case to make comparision works + std::replace(str.begin(), str.end(), '-', '_'); +} + +bool TestRunner::filterGroupsByXmls(const std::vector & files) +{ + DECLARE_EXCEPTION_TYPE(DPL::Exception, XMLError) + + const std::string idPath = "/test_definition/suite/set/testcase/@id"; + + bool success = true; + std::map casesMap; + + std::string testsuite; + if(!m_testGroups.empty()) + { + for(TestCaseGroupMap::const_iterator cit = m_testGroups.begin(); cit != m_testGroups.end(); ++cit) + { + if(!cit->second.empty()) + { + for(TestCaseStructList::const_iterator cj = cit->second.begin(); cj != cit->second.end(); ++cj) + { + std::string name = cj->name; + std::string::size_type st = name.find('_'); + if(st != std::string::npos) + { + name = name.substr(0, st); + testsuite = name; + break; + } + } + if(!testsuite.empty()) break; + } + } + } + + xmlInitParser(); + LIBXML_TEST_VERSION + xmlXPathInit(); + + Try + { + FOREACH(file, files) + { + xmlDocPtr doc; + xmlXPathContextPtr xpathCtx; + + doc = xmlReadFile(file->c_str(), NULL, 0); + if (doc == NULL) { + ThrowMsg(XMLError, "File Problem"); + } else { + //context + xpathCtx = xmlXPathNewContext(doc); + if (xpathCtx == NULL) { + ThrowMsg(XMLError, + "Error: unable to create new XPath context\n"); + } + xpathCtx->node = xmlDocGetRootElement(doc); + } + + std::string result; + xmlXPathObjectPtr xpathObject; + //get requested node's values + xpathObject = xmlXPathEvalExpression(BAD_CAST idPath.c_str(), xpathCtx); + if (xpathObject == NULL) + { + ThrowMsg(XMLError, "XPath evaluation failure: " << idPath); + } + xmlNodeSetPtr nodes = xpathObject->nodesetval; + unsigned size = (nodes) ? nodes->nodeNr : 0; + LogDebug("Found " << size << " nodes matching xpath"); + for(unsigned i = 0; i < size; ++i) + { + LogPedantic("Type: " << nodes->nodeTab[i]->type); + if (nodes->nodeTab[i]->type == XML_ATTRIBUTE_NODE) { + xmlNodePtr curNode = nodes->nodeTab[i]; + result = getXMLNode(curNode); + LogPedantic("Result: " << result); + normalizeXMLTag(result, testsuite); + casesMap.insert(make_pair(result, false)); + } + } + //Cleanup of XPath data + xmlXPathFreeObject(xpathObject); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); + } + } + Catch(XMLError) + { + LogError("Libxml error: " << _rethrown_exception.DumpToString()); + success = false; + } + xmlCleanupParser(); + + if(!filterByXML(casesMap)) + { + success = false; + } + + return success; +} + +bool TestRunner::filterByXML(std::map & casesMap) +{ + FOREACH(group, m_testGroups) { + TestCaseStructList newList; + FOREACH(iterator, group->second) + { + if (casesMap.find(iterator->name) != casesMap.end()) { + casesMap[iterator->name] = true; + newList.push_back(*iterator); + } + } + group->second = newList; + } + FOREACH(cs, casesMap) + { + if(cs->second == false) + { + LogError("Cannot find testcase from XML file: " << cs->first); + return false; + } + } + return true; +} + +TestRunner::Status TestRunner::RunTestCase(const TestCaseStruct& testCase) +{ + try { + testCase.proc(); + } catch (const TestFailed &e) { + // Simple test failure + CollectResult(testCase.name, + "", + TestResultsCollectorBase::FailStatus::FAILED, + e.GetMessage()); + return FAILED; + } catch (const Ignored &e) { + if (m_runIgnored) { + // Simple test have to be implemented + CollectResult(testCase.name, + "", + TestResultsCollectorBase::FailStatus::IGNORED, + e.GetMessage()); + } + + return IGNORED; + } catch (const DPL::Exception &e) { + // DPL exception failure + CollectResult(testCase.name, + "", + TestResultsCollectorBase::FailStatus::INTERNAL, + "DPL exception:" + e.GetMessage() + "\n" + e.DumpToString()); + + return FAILED; + } catch (const std::exception &) { + // std exception failure + CollectResult(testCase.name, + "", + TestResultsCollectorBase::FailStatus::INTERNAL, + "std exception"); + + return FAILED; + } catch (...) { + // Unknown exception failure + CollectResult(testCase.name, + "", + TestResultsCollectorBase::FailStatus::INTERNAL, + "unknown exception"); + + return FAILED; + } + + CollectResult(testCase.name, + "", + TestResultsCollectorBase::FailStatus::NONE); + + // Everything OK + return PASS; +} + +void TestRunner::RunTests() +{ + using namespace DPL::Colors::Text; + + Banner(); + + unsigned count = 0; + FOREACH(group, m_testGroups) { + count += group->second.size(); + } + + std::for_each(m_collectors.begin(), + m_collectors.end(), + [count] (const TestResultsCollectors::value_type & collector) + { + collector.second->Start(count); + }); + + fprintf(stderr, "%sFound %d testcases...%s\n", GREEN_BEGIN, count, GREEN_END); + fprintf(stderr, "%s%s%s\n", GREEN_BEGIN, "Running tests...", GREEN_END); + FOREACH(group, m_testGroups) { + TestCaseStructList list = group->second; + if (!list.empty()) { + std::for_each( + m_collectors.begin(), + m_collectors.end(), + [&group](const TestResultsCollectors::value_type & collector) + { + collector.second-> + CollectCurrentTestGroupName(group->first); + }); + list.sort(); + + for (TestCaseStructList::const_iterator iterator = list.begin(); + iterator != list.end(); + ++iterator) + { + TestCaseStruct test = *iterator; + if (m_startTestId == test.name) { + m_startTestId = ""; + } + + if (m_startTestId.empty()) { + RunTestCase(test); + } + if (m_terminate == true) { + // Terminate quietly without any logs + return; + } + } + } + } + + std::for_each(m_collectors.begin(), + m_collectors.end(), + [] (const TestResultsCollectors::value_type & collector) + { + collector.second->Finish(); + }); + + // Finished + fprintf(stderr, "%s%s%s\n\n", GREEN_BEGIN, "Finished", GREEN_END); +} + +void TestRunner::CollectResult( + const std::string& id, + const std::string& description, + const TestResultsCollectorBase::FailStatus::Type status, + const std::string& reason) +{ + std::for_each(m_collectors.begin(), + m_collectors.end(), + [&](const TestResultsCollectors::value_type & collector) + { + collector.second->CollectResult(id, + description, + status, + reason); + }); +} + +void TestRunner::Banner() +{ + using namespace DPL::Colors::Text; + fprintf(stderr, + "%s%s%s\n", + BOLD_GREEN_BEGIN, + "DPL tests runner", + BOLD_GREEN_END); + fprintf(stderr, + "%s%s%s%s\n\n", + GREEN_BEGIN, + "Build: ", + __TIMESTAMP__, + GREEN_END); +} + +void TestRunner::InvalidArgs(const std::string& message) +{ + using namespace DPL::Colors::Text; + fprintf(stderr, + "%s%s%s\n", + BOLD_RED_BEGIN, + message.c_str(), + BOLD_RED_END); +} + +void TestRunner::Usage() +{ + fprintf(stderr, "Usage: runner [options]\n\n"); + fprintf(stderr, "Output type:\n"); + fprintf(stderr, " --output= --output= ...\n"); + fprintf(stderr, "\n possible output types:\n"); + FOREACH(type, TestResultsCollectorBase::GetCollectorsNames()) { + fprintf(stderr, " --output=%s\n", type->c_str()); + } + fprintf(stderr, "\n example:\n"); + fprintf(stderr, + " test-binary --output=text --output=xml --file=output.xml\n\n"); + fprintf(stderr, "Other parameters:\n"); + fprintf(stderr, + " --regexp='regexp'\t Only selected tests" + " which names match regexp run\n\n"); + fprintf(stderr, " --start=\tStart from concrete test id"); + fprintf(stderr, " --group=\t Run tests only from one group\n"); + fprintf(stderr, " --runignored\t Run also ignored tests\n"); + fprintf(stderr, " --list\t Show a list of Test IDs\n"); + fprintf(stderr, " --listgroups\t Show a list of Test Group names \n"); + fprintf(stderr, " --only-from-xml=\t Run only testcases specified in XML file \n" + " XML name is taken from attribute id=\"part1_part2\" as whole.\n" + " If part1 is not found (no _) then it is implicitily " + "set according to suite part1 from binary tests\n"); + fprintf( + stderr, + " --listingroup=\t Show a list of Test IDS in one group\n"); + fprintf(stderr, " --allowchildlogs\t Allow to print logs from child process on screen.\n"); + fprintf(stderr, " When active child process will be able to print logs on stdout and stderr.\n"); + fprintf(stderr, " Both descriptors will be closed after test.\n"); + fprintf(stderr, " --help\t This help\n\n"); + std::for_each(m_collectors.begin(), + m_collectors.end(), + [] (const TestResultsCollectors::value_type & collector) + { + fprintf(stderr, + "Output %s has specific args:\n", + collector.first.c_str()); + fprintf(stderr, + "%s\n", + collector.second-> + CollectorSpecificHelp().c_str()); + }); + fprintf(stderr, "For bug reporting, please write to:\n"); + fprintf(stderr, "\n"); +} + +int TestRunner::ExecTestRunner(int argc, char *argv[]) +{ + std::vector args; + for (int i = 0; i < argc; ++i) { + args.push_back(argv[i]); + } + return ExecTestRunner(args); +} + +void TestRunner::MarkAssertion() +{ + ++m_totalAssertions; +} + +int TestRunner::ExecTestRunner(const ArgsList& value) +{ + m_runIgnored = false; + ArgsList args = value; + // Parse command line + if (args.size() == 1) { + InvalidArgs(); + Usage(); + return -1; + } + + args.erase(args.begin()); + + bool showHelp = false; + bool justList = false; + std::vector xmlFiles; + + TestResultsCollectorBasePtr currentCollector; + + // Parse each argument + FOREACH(it, args) + { + std::string arg = *it; + const std::string regexp = "--regexp="; + const std::string output = "--output="; + const std::string groupId = "--group="; + const std::string runIgnored = "--runignored"; + const std::string listCmd = "--list"; + const std::string startCmd = "--start="; + const std::string listGroupsCmd = "--listgroups"; + const std::string listInGroup = "--listingroup="; + const std::string allowChildLogs = "--allowchildlogs"; + const std::string onlyFromXML = "--only-from-xml="; + + if (currentCollector) { + if (currentCollector->ParseCollectorSpecificArg(arg)) { + continue; + } + } + + if (arg.find(startCmd) == 0) { + arg.erase(0, startCmd.length()); + FOREACH(group, m_testGroups) { + FOREACH(tc, group->second) { + if (tc->name == arg) { + m_startTestId = arg; + break; + } + } + if (!m_startTestId.empty()) { + break; + } + } + if (!m_startTestId.empty()) { + continue; + } + InvalidArgs(); + fprintf(stderr, "Start test id has not been found\n"); + Usage(); + return 0; + } else if (arg.find(groupId) == 0) { + arg.erase(0, groupId.length()); + TestCaseGroupMap::iterator found = m_testGroups.find(arg); + if (found != m_testGroups.end()) { + std::string name = found->first; + TestCaseStructList newList = found->second; + m_testGroups.clear(); + m_testGroups[name] = newList; + } else { + fprintf(stderr, "Group %s not found\n", arg.c_str()); + InvalidArgs(); + Usage(); + return -1; + } + } else if (arg == runIgnored) { + m_runIgnored = true; + } else if (arg == listCmd) { + justList = true; + } else if (arg == listGroupsCmd) { + FOREACH(group, m_testGroups) { + printf("GR:%s\n", group->first.c_str()); + } + return 0; + } else if (arg.find(listInGroup) == 0) { + arg.erase(0, listInGroup.length()); + FOREACH(test, m_testGroups[arg]) { + printf("ID:%s\n", test->name.c_str()); + } + return 0; + } else if (arg.find(allowChildLogs) == 0) { + arg.erase(0, allowChildLogs.length()); + m_allowChildLogs = true; + } else if (arg == "--help") { + showHelp = true; + } else if (arg.find(output) == 0) { + arg.erase(0, output.length()); + if (m_collectors.find(arg) != m_collectors.end()) { + InvalidArgs( + "Multiple outputs of the same type are not supported!"); + Usage(); + return -1; + } + currentCollector.reset(TestResultsCollectorBase::Create(arg)); + if (!currentCollector) { + InvalidArgs("Unsupported output type!"); + Usage(); + return -1; + } + m_collectors[arg] = currentCollector; + } else if (arg.find(regexp) == 0) { + arg.erase(0, regexp.length()); + if (arg.length() == 0) { + InvalidArgs(); + Usage(); + return -1; + } + + if (arg[0] == '\'' && arg[arg.length() - 1] == '\'') { + arg.erase(0); + arg.erase(arg.length() - 1); + } + + if (arg.length() == 0) { + InvalidArgs(); + Usage(); + return -1; + } + + pcrecpp::RE re(arg.c_str()); + FOREACH(group, m_testGroups) { + TestCaseStructList newList; + FOREACH(iterator, group->second) + { + if (re.PartialMatch(iterator->name)) { + newList.push_back(*iterator); + } + } + group->second = newList; + } + } else if(arg.find(onlyFromXML) == 0) { + arg.erase(0, onlyFromXML.length()); + if (arg.length() == 0) { + InvalidArgs(); + Usage(); + return -1; + } + + if (arg[0] == '\'' && arg[arg.length() - 1] == '\'') { + arg.erase(0); + arg.erase(arg.length() - 1); + } + + if (arg.length() == 0) { + InvalidArgs(); + Usage(); + return -1; + } + + xmlFiles.push_back(arg); + } else { + InvalidArgs(); + Usage(); + return -1; + } + } + + if(!xmlFiles.empty()) + { + if(!filterGroupsByXmls(xmlFiles)) + { + fprintf(stderr, "XML file is not correct\n"); + return 0; + } + } + + if(justList) + { + FOREACH(group, m_testGroups) { + FOREACH(test, group->second) { + printf("ID:%s:%s\n", group->first.c_str(), test->name.c_str()); + } + } + return 0; + } + + currentCollector.reset(); + + // Show help + if (showHelp) { + Usage(); + return 0; + } + + if (m_collectors.empty()) { + TestResultsCollectorBasePtr collector( + TestResultsCollectorBase::Create("text")); + m_collectors["text"] = collector; + } + + for (auto it = m_collectors.begin(); it != m_collectors.end(); ++it) { + if (!it->second->Configure()) { + fprintf(stderr, "Could not configure selected output"); + return 0; + } + } + + // Run tests + RunTests(); + + return 0; +} + +bool TestRunner::getRunIgnored() const +{ + return m_runIgnored; +} + +void TestRunner::Terminate() +{ + m_terminate = true; +} + +bool TestRunner::GetAllowChildLogs() +{ + return m_allowChildLogs; +} + +} +} // namespace DPL diff --git a/modules/test/src/test_runner_child.cpp b/modules/test/src/test_runner_child.cpp new file mode 100644 index 0000000..8e793e8 --- /dev/null +++ b/modules/test/src/test_runner_child.cpp @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_runner_child.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test runner + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +const int CHILD_TEST_FAIL = 0; +const int CHILD_TEST_PASS = 1; +const int CHILD_TEST_IGNORED = 2; + +int closeOutput() { + int devnull; + int retcode = -1; + if (-1 == (devnull = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY)))) + return -1; + + // replace stdout with /dev/null + if (-1 == TEMP_FAILURE_RETRY(dup2(devnull, STDOUT_FILENO))) + goto end; + + // replace stderr with /dev/null + if (-1 == TEMP_FAILURE_RETRY(dup2(devnull, STDERR_FILENO))) + goto end; + + retcode = 0; + +end: + close(devnull); + return retcode; +} + +} // namespace anonymous + +namespace DPL { +namespace Test { + +PipeWrapper::PipeWrapper() +{ + if (-1 == pipe(m_pipefd)) { + m_pipefd[0] = PIPE_CLOSED; + m_pipefd[1] = PIPE_CLOSED; + } +} + +PipeWrapper::~PipeWrapper() +{ + closeHelp(0); + closeHelp(1); +} + +bool PipeWrapper::isReady() +{ + return m_pipefd[0] != PIPE_CLOSED || m_pipefd[1] != PIPE_CLOSED; +} + +void PipeWrapper::setUsage(Usage usage) +{ + if (usage == READONLY) { + closeHelp(1); + } + if (usage == WRITEONLY) { + closeHelp(0); + } +} + +PipeWrapper::Status PipeWrapper::send(int code, std::string &message) +{ + if (m_pipefd[1] == PIPE_CLOSED) { + return ERROR; + } + + std::ostringstream output; + output << toBinaryString(code); + output << toBinaryString(static_cast(message.size())); + output << message; + + std::string binary = output.str(); + int size = binary.size(); + + if ((writeHelp(&size, + sizeof(int)) == ERROR) || + (writeHelp(binary.c_str(), size) == ERROR)) + { + return ERROR; + } + return SUCCESS; +} + +PipeWrapper::Status PipeWrapper::receive(int &code, std::string &data, time_t deadline) +{ + if (m_pipefd[0] == PIPE_CLOSED) { + return ERROR; + } + + int size; + Status ret; + + if ((ret = readHelp(&size, sizeof(int), deadline)) != SUCCESS) { + return ret; + } + + std::vector buffer; + buffer.resize(size); + + if ((ret = readHelp(&buffer[0], size, deadline)) != SUCCESS) { + return ret; + } + + try { + DPL::BinaryQueue queue; + queue.AppendCopy(&buffer[0], size); + + queue.FlattenConsume(&code, sizeof(int)); + queue.FlattenConsume(&size, sizeof(int)); + + buffer.resize(size); + + queue.FlattenConsume(&buffer[0], size); + data.assign(buffer.begin(), buffer.end()); + } catch (DPL::BinaryQueue::Exception::Base &e) { + return ERROR; + } + return SUCCESS; +} + +void PipeWrapper::closeAll() +{ + closeHelp(0); + closeHelp(1); +} + +std::string PipeWrapper::toBinaryString(int data) +{ + char buffer[sizeof(int)]; + memcpy(buffer, &data, sizeof(int)); + return std::string(buffer, buffer + sizeof(int)); +} + +void PipeWrapper::closeHelp(int desc) +{ + if (m_pipefd[desc] != PIPE_CLOSED) { + TEMP_FAILURE_RETRY(close(m_pipefd[desc])); + m_pipefd[desc] = PIPE_CLOSED; + } +} + +PipeWrapper::Status PipeWrapper::writeHelp(const void *buffer, int size) +{ + int ready = 0; + const char *p = static_cast(buffer); + while (ready != size) { + int ret = write(m_pipefd[1], &p[ready], size - ready); + + if (ret == -1 && (errno == EAGAIN || errno == EINTR)) { + continue; + } + + if (ret == -1) { + closeHelp(1); + return ERROR; + } + + ready += ret; + } + return SUCCESS; +} + +PipeWrapper::Status PipeWrapper::readHelp(void *buf, int size, time_t deadline) +{ + int ready = 0; + char *buffer = static_cast(buf); + while (ready != size) { + time_t wait = deadline - time(0); + wait = wait < 1 ? 1 : wait; + pollfd fds = { m_pipefd[0], POLLIN, 0 }; + + int pollReturn = poll(&fds, 1, wait * 1000); + + if (pollReturn == 0) { + return TIMEOUT; // Timeout + } + + if (pollReturn < -1) { + return ERROR; + } + + int ret = read(m_pipefd[0], &buffer[ready], size - ready); + + if (ret == -1 && (errno == EAGAIN || errno == EINTR)) { + continue; + } + + if (ret == -1 || ret == 0) { + closeHelp(0); + return ERROR; + } + + ready += ret; + } + return SUCCESS; +} + +void RunChildProc(TestRunner::TestCase procChild) +{ + PipeWrapper pipe; + if (!pipe.isReady()) { + throw TestRunner::TestFailed("Pipe creation failed"); + } + + pid_t pid = fork(); + + if (pid == -1) { + throw TestRunner::TestFailed("Child creation failed"); + } + + if (pid != 0) { + // parent code + pipe.setUsage(PipeWrapper::READONLY); + + int code; + std::string message; + + int pipeReturn = pipe.receive(code, message, time(0) + 10); + + if (pipeReturn != PipeWrapper::SUCCESS) { // Timeout or reading error + pipe.closeAll(); + kill(pid, SIGKILL); + } + + int status; + waitpid(pid, &status, 0); + + if (pipeReturn == PipeWrapper::TIMEOUT) { + throw TestRunner::TestFailed("Timeout"); + } + + if (pipeReturn == PipeWrapper::ERROR) { + throw TestRunner::TestFailed("Reading pipe error"); + } + + if (code == CHILD_TEST_FAIL) { + throw TestRunner::TestFailed(message); + } else if (code == CHILD_TEST_IGNORED) { + throw TestRunner::Ignored(message); + } + } else { + // child code + + // End Runner after current test + TestRunnerSingleton::Instance().Terminate(); + + int code = CHILD_TEST_PASS; + std::string msg; + + bool allowLogs = TestRunnerSingleton::Instance().GetAllowChildLogs(); + + close(STDIN_FILENO); + if (!allowLogs) { + closeOutput(); // if fails nothing we can do + } + + pipe.setUsage(PipeWrapper::WRITEONLY); + + try { + procChild(); + } catch (const DPL::Test::TestRunner::TestFailed &e) { + msg = e.GetMessage(); + code = CHILD_TEST_FAIL; + } catch (const DPL::Test::TestRunner::Ignored &e) { + msg = e.GetMessage(); + code = CHILD_TEST_IGNORED; + } catch (...) { // catch all exception generated by "user" code + msg = "unhandled exeception"; + code = CHILD_TEST_FAIL; + } + + if (allowLogs) { + closeOutput(); + } + + pipe.send(code, msg); + } +} +} // namespace Test +} // namespace DPL diff --git a/modules/test/src/test_runner_multiprocess.cpp b/modules/test/src/test_runner_multiprocess.cpp new file mode 100644 index 0000000..691966f --- /dev/null +++ b/modules/test/src/test_runner_multiprocess.cpp @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_runner_multiprocess.cpp + * @author Marcin Niesluchowski (m.niesluchow@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of multiprocess test runner + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +const int MULTI_TEST_ERROR = -1; +const int MULTI_TEST_PASS = 0; +const int MULTI_TEST_FAILED = 1; +const int MULTI_TEST_IGNORED = 2; +const int MULTI_TEST_INTERNAL = 3; + +} + +namespace DPL { +namespace Test { + +SimplePipeWrapper::SimplePipeWrapper() +: PipeWrapper() +{ + +} + +SimplePipeWrapper::~SimplePipeWrapper() +{ + +} + +PipeWrapper::Status SimplePipeWrapper::send(std::string &message) +{ + if (m_pipefd[1] == PIPE_CLOSED) { + return ERROR; + } + + if (message.size() > PIPE_BUF-1) { + return ERROR; + } + + char buffer[PIPE_BUF] = { 0 }; + + + for(unsigned int i = 0; i < message.size(); ++i) { + buffer[i] = message[i]; + } + + return writeHelp(buffer, PIPE_BUF); +} + +PipeWrapper::Status SimplePipeWrapper::receive(std::string &data, bool &empty, time_t deadline) +{ + if (m_pipefd[0] == PIPE_CLOSED) { + return ERROR; + } + + empty = false; + + data.resize(PIPE_BUF); + + char buffer[PIPE_BUF] = { 0 }; + + int ready = 0; + while (ready != PIPE_BUF) { + time_t wait = deadline - time(0); + wait = wait < 1 ? 1 : wait; + pollfd fds = { m_pipefd[0], POLLIN, 0 }; + + int pollReturn = poll(&fds, 1, wait * 1000); + + if (pollReturn == 0) { + return TIMEOUT; // Timeout + } + + if (pollReturn < -1) { + return ERROR; + } + int ret = read(m_pipefd[0], &buffer[ready], PIPE_BUF - ready); + if (ret == -1 && (errno == EAGAIN || errno == EINTR)) { + continue; + } + + if (ret == -1) { + closeHelp(0); + return ERROR; + } + if (ret == 0) { + empty = true; + break; + } + + ready += ret; + } + + + for(unsigned int i = 0; i < PIPE_BUF; ++i){ + if(buffer[i] == 0) { + data.resize(i); + return SUCCESS; + } + data[i] = buffer[i]; + } + + return ERROR; +} + +void RunMultiProc(TestRunner::TestCase procMulti) +{ + SimplePipeWrapper pipe; + int code = MULTI_TEST_PASS; + std::string msg = ""; + int pipeReturn; + + int waitStatus; + + pid_t top_pid = getpid(); + + if (!pipe.isReady()) { + throw TestRunner::TestFailed("Pipe creation failed"); + } + // pipe + + try { + procMulti(); + } catch (const TestRunner::TestFailed &e) { + code = MULTI_TEST_FAILED; + msg = e.GetMessage(); + } catch (const TestRunner::Ignored &e) { + code = MULTI_TEST_IGNORED; + msg = e.GetMessage(); + } catch (const DPL::Exception &e) { + code = MULTI_TEST_INTERNAL; + msg = "DPL exception:" + e.GetMessage(); + } catch (const std::exception &) { + code = MULTI_TEST_INTERNAL; + msg = "std exception"; + } catch (...) { + // Unknown exception failure + code = MULTI_TEST_INTERNAL; + msg = "unknown exception"; + } + + while (true) { + pid_t child_pid = wait(&waitStatus); + if (child_pid == -1) { + if (errno == ECHILD) { + if (top_pid == getpid()) { + std::string recMsg=""; + + pipe.setUsage(PipeWrapper::READONLY); + + bool empty=false; + while(true) { + pipeReturn = pipe.receive(recMsg, empty, time(0) + 10); + + if (empty) { + break; + } + if (pipeReturn == PipeWrapper::ERROR) { + pipe.closeAll(); + throw TestRunner::TestFailed("Reading pipe error"); + } else if (pipeReturn == PipeWrapper::TIMEOUT) { + pipe.closeAll(); + throw TestRunner::TestFailed("Timeout error"); + } + msg = msg + "\n" + recMsg; + } + pipe.closeAll(); + + switch(code) { + case MULTI_TEST_PASS: + return; + case MULTI_TEST_FAILED: + throw TestRunner::TestFailed(msg); + case MULTI_TEST_IGNORED: + throw TestRunner::Ignored(msg); + case MULTI_TEST_INTERNAL: + throw TestRunner::TestFailed(msg); + default: + throw TestRunner::TestFailed(msg); + } + } else { + pipe.setUsage(PipeWrapper::WRITEONLY); + + pipeReturn = pipe.send(msg); + + if (pipeReturn == PipeWrapper::ERROR) { + pipe.closeAll(); + code = MULTI_TEST_ERROR; + } + + exit(code); + } + } + } else if (WIFEXITED(waitStatus)) { + if ((signed char)WEXITSTATUS(waitStatus) == MULTI_TEST_FAILED) { + switch (code) { + case MULTI_TEST_PASS: + code = MULTI_TEST_FAILED; + break; + case MULTI_TEST_FAILED: + break; + case MULTI_TEST_IGNORED: + code = MULTI_TEST_FAILED; + break; + case MULTI_TEST_INTERNAL: + break; + default: + break; + } + } else if ((signed char)WEXITSTATUS(waitStatus) == MULTI_TEST_IGNORED) { + switch (code) { + case MULTI_TEST_PASS: + code = MULTI_TEST_IGNORED; + break; + case MULTI_TEST_FAILED: + break; + case MULTI_TEST_IGNORED: + break; + case MULTI_TEST_INTERNAL: + break; + default: + break; + } + } else if ((signed char)WEXITSTATUS(waitStatus) == MULTI_TEST_INTERNAL) { + switch (code) { + case MULTI_TEST_PASS: + code = MULTI_TEST_INTERNAL; + break; + case MULTI_TEST_FAILED: + code = MULTI_TEST_INTERNAL; + break; + case MULTI_TEST_IGNORED: + code = MULTI_TEST_INTERNAL; + break; + case MULTI_TEST_INTERNAL: + break; + default: + break; + } + } else if ((signed char)WEXITSTATUS(waitStatus) != MULTI_TEST_PASS) { + code = MULTI_TEST_ERROR; + msg = "PROCESS BAD CODE RETURN"; + } + } + } +} +} // namespace Test +} // namespace DPL diff --git a/modules/test/src/value_separated_policies.cpp b/modules/test/src/value_separated_policies.cpp new file mode 100644 index 0000000..0ecf599 --- /dev/null +++ b/modules/test/src/value_separated_policies.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file value_separated_policies.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief ... + */ + +#include +#include +#include + +namespace DPL { + +std::string CSVTokenizerPolicy::GetSeperators() +{ + return ","; +} + +bool CSVTokenizerPolicy::SkipEmpty() +{ + return false; +} + +void CSVTokenizerPolicy::PrepareValue(std::string &) +{ +} + +bool CSVTokenizerPolicy::TryAgainAtEnd(int) +{ + return false; +} + +bool CSVParserPolicy::SkipLine(const std::vector & ) +{ + return false; +} + +bool CSVParserPolicy::Validate(std::shared_ptr > > & result) +{ + int num = -1; + FOREACH(r, *result) + { + int size = r->size(); + if(num != -1 && num != size) + { + LogError("Columns not matches"); + return false; + } + num = size; + } + return true; +} + +} diff --git a/modules/test/src/value_separated_tokens.cpp b/modules/test/src/value_separated_tokens.cpp new file mode 100644 index 0000000..4b53e27 --- /dev/null +++ b/modules/test/src/value_separated_tokens.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file value_separated_tokens.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief ... + */ + +#include + +namespace DPL { + +VSToken::VSToken(const std::string & c) : m_newline(false), m_cell(c) +{ +} + +VSToken::VSToken() : m_newline(true) +{ +} + +const std::string & VSToken::cell() const +{ + return m_cell; +} + +bool VSToken::isNewLine() +{ + return m_newline; +} + +} diff --git a/modules/utils/config.cmake b/modules/utils/config.cmake new file mode 100644 index 0000000..828ca6c --- /dev/null +++ b/modules/utils/config.cmake @@ -0,0 +1,49 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# @file config.cmake +# @author Soyoung Kim(sy037.kim@samsung.com) +# @version 1.0 +# @brief +# + +SET(DPL_UTILS_SOURCES + ${PROJECT_SOURCE_DIR}/modules/utils/src/bash_utils.cpp + ${PROJECT_SOURCE_DIR}/modules/utils/src/folder_size.cpp + ${PROJECT_SOURCE_DIR}/modules/utils/src/mime_type_utils.cpp + ${PROJECT_SOURCE_DIR}/modules/utils/src/warp_iri.cpp + ${PROJECT_SOURCE_DIR}/modules/utils/src/widget_version.cpp + ${PROJECT_SOURCE_DIR}/modules/utils/src/wrt_global_settings.cpp + ${PROJECT_SOURCE_DIR}/modules/utils/src/wrt_utility.cpp + ${PROJECT_SOURCE_DIR}/modules/utils/src/path.cpp + PARENT_SCOPE +) + +SET(DPL_UTILS_HEADERS + ${PROJECT_SOURCE_DIR}/modules/utils/include/dpl/utils/bash_utils.h + ${PROJECT_SOURCE_DIR}/modules/utils/include/dpl/utils/folder_size.h + ${PROJECT_SOURCE_DIR}/modules/utils/include/dpl/utils/mime_type_utils.h + ${PROJECT_SOURCE_DIR}/modules/utils/include/dpl/utils/warp_iri.h + ${PROJECT_SOURCE_DIR}/modules/utils/include/dpl/utils/widget_version.h + ${PROJECT_SOURCE_DIR}/modules/utils/include/dpl/utils/wrt_global_settings.h + ${PROJECT_SOURCE_DIR}/modules/utils/include/dpl/utils/wrt_utility.h + ${PROJECT_SOURCE_DIR}/modules/utils/include/dpl/utils/path.h + PARENT_SCOPE +) + +SET(DPL_UTILS_INCLUDE_DIR + ${PROJECT_SOURCE_DIR}/modules/utils/include + PARENT_SCOPE +) diff --git a/modules/utils/include/dpl/utils/bash_utils.h b/modules/utils/include/dpl/utils/bash_utils.h new file mode 100644 index 0000000..33a5f9d --- /dev/null +++ b/modules/utils/include/dpl/utils/bash_utils.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file bash_utils.h + * @author Iwanek Tomasz + * @version 1.0 + */ + +#ifndef BASH_UTILS_H +#define BASH_UTILS_H + +#include + +namespace BashUtils { +/** + * Escapes bash special characters in string and return string in double quotes + * @param source string to be escaped + * @return escaped string + */ +std::string escape_arg(const std::string & source); +} + +#endif // BASH_UTILS_H diff --git a/modules/utils/include/dpl/utils/folder_size.h b/modules/utils/include/dpl/utils/folder_size.h new file mode 100644 index 0000000..71a77bd --- /dev/null +++ b/modules/utils/include/dpl/utils/folder_size.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * + * @file folder_size.h + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief Declaration for function calculating directory size + */ + +#ifndef SRC_COMMON_FOLDER_SIZE_H_ +#define SRC_COMMON_FOLDER_SIZE_H_ + +#include + +#include + +namespace Utils { +size_t getFolderSize(const std::string& path); + +DPL::String fromFileSizeString(size_t fileSize); +} + +#endif /* SRC_COMMON_FOLDER_SIZE_H_ */ diff --git a/modules/utils/include/dpl/utils/mime_type_utils.h b/modules/utils/include/dpl/utils/mime_type_utils.h new file mode 100644 index 0000000..1d93385 --- /dev/null +++ b/modules/utils/include/dpl/utils/mime_type_utils.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MIME_TYPE_UTILS_H +#define MIME_TYPE_UTILS_H + +#include +#include + +class MimeTypeUtils +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InvalidFileName) + }; + + private: + //TODO use hash_map if possible + static const std::set& getMimeTypesSupportedForIcon(); + static const std::set& getMimeTypesSupportedForStartFile(); + + typedef std::map FileIdentificationMap; + + static DPL::String getFileNameFromPath(const DPL::String& path); + static const FileIdentificationMap& getFileIdentificationMap(); + static DPL::String stripMimeParameters(const DPL::String& mimeType); + + public: + typedef std::map MimeAttributes; + static bool isValidIcon(const DPL::String& path); + static bool isValidStartFile(const DPL::String& path, + const DPL::OptionalString& providedMimeType); + static bool isMimeTypeSupportedForStartFile(const DPL::String& mimeType); + static bool isMimeTypeSupportedForIcon(const DPL::String& mimeType); + static MimeAttributes getMimeAttributes(const DPL::String& mimeType); + ///implements 9.1.10. (Rule for Identifying the Media Type of a File) + ///from W3C packaging specification + static DPL::String identifyFileMimeType(const DPL::String& path); +}; + +#endif /* MIME_TYPE_UTILS_H */ + diff --git a/modules/utils/include/dpl/utils/path.h b/modules/utils/include/dpl/utils/path.h new file mode 100644 index 0000000..83290d0 --- /dev/null +++ b/modules/utils/include/dpl/utils/path.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file path.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + */ +#ifndef PATH_H +#define PATH_H + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace DPL { +namespace Utils { +class Path; +} +} + +std::ostream & operator<<(std::ostream & str, const DPL::Utils::Path & path); + +namespace DPL { +namespace Utils { +/** + * @brief The Path class path abstraction + * + * Class for expressing paths not limited not existing ones. + * It's possible to check if path exists, remove it or iterate it if it's directory + * + * Created Path object allways contains absolute path, never relative path. + * Simplifies common usage cases: + * - path construction (with /= and / operators) + * - directory iterator (begin(), end(), iterator construction) + * - receiving filenames and directory names of given paths + * - checking what is pointed by path (Exists(), IsFile(), IsDir()) + * + * Check tests for details of usage. + */ +class Path +{ +public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, BaseException) + DECLARE_EXCEPTION_TYPE(BaseException, AlreadyExists) //path already exists + DECLARE_EXCEPTION_TYPE(BaseException, NotPrefix) //given path is not prefix of this path + DECLARE_EXCEPTION_TYPE(BaseException, NotExists) //file not exists + DECLARE_EXCEPTION_TYPE(BaseException, NotDirectory) //directory nto exists + DECLARE_EXCEPTION_TYPE(BaseException, OperationFailed) //operation failed due to system error(permission etc..) + DECLARE_EXCEPTION_TYPE(BaseException, EmptyPath) //object cannot be constructed with empty path + DECLARE_EXCEPTION_TYPE(BaseException, InternalError) //internal error / wrong path usage + DECLARE_EXCEPTION_TYPE(BaseException, CannotCopy) //cannot make copy + DECLARE_EXCEPTION_TYPE(BaseException, RootDirectoryError) //operation cannot be done with root diretory + + class Iterator : public std::iterator + { + public: + Iterator(); + Iterator(const char *); + Iterator& operator++(); + Iterator operator++(int); + bool operator==(const Iterator& rhs) const; + bool operator!=(const Iterator& rhs) const; + const Path & operator*(); + const Path * operator->(); + private: + void ReadNext(); + + std::shared_ptr m_dir; + std::shared_ptr m_path; + std::shared_ptr m_root; + }; + + explicit Path(const DPL::String & str); + explicit Path(const std::string & str); + explicit Path(const char * str); + Path(); + + /** + * @brief DirectoryPath shell's dirname equivalent as path + * @return directory path + */ + Path DirectoryPath() const; + /** + * @brief DirectoryName shell's dirname equivalent + * @return directory name of given path + */ + std::string DirectoryName() const; + /** + * @brief Basename shell's basename equivalent + * @return base name of given path + */ + std::string Filename() const; + /** + * @brief Fullpath fullpath based on current working diretory + * @return full path + */ + std::string Fullpath() const; + /** + * @brief Extension + * @return extension + */ + std::string Extension() const; + + bool Exists() const; + bool IsDir() const; + bool IsFile() const; + bool ExistsAndIsFile() const; + bool ExistsAndIsDir() const; + bool IsSymlink() const; + std::size_t Size() const; + /** + * @brief isSubPath Returns relative path to given base + * @param prefix base path + * @return reltive path + * + * @throws If prefix does not match to this path object + */ + bool isSubPath(const Path & other) const; + bool hasExtension(const std::string& extension) const; + + bool operator==(const Path & other) const; + bool operator!=(const Path & other) const; + + //appending to path + Path operator/(const DPL::String& part) const; + Path operator/(const std::string& part) const; + Path operator/(const char * part) const; + + Path & operator/=(const DPL::String& part); + Path & operator/=(const std::string& part); + Path & operator/=(const char * part); + + //foreach + Iterator begin() const; + Iterator end() const; + + //root error - throws error on root directory + void RootGuard() const; + +private: + + void Append(const std::string& part); + void Construct(const std::string & src); + + std::vector m_parts; + + friend std::ostream & ::operator<<(std::ostream & str, const DPL::Utils::Path & path); +}; + +/** + * @brief MkDir creates 'current path' as directory + * @param path path + * @param mode mode + */ +void MakeDir(const Path & path, mode_t mode = 0755); + +/** + * @brief MkFile creates 'current path' as empty file + * @param path path + */ +void MakeEmptyFile(const Path & path); + +/** + * @brief Remove removes 'current path' + * @param path path to remove + */ +void Remove(const Path & path); + +/** + * @brief TryRemove tries to remvoe path + * @param path returns status of removal + */ +bool TryRemove(const Path & path); + +/** + * @brief Rename renames(moves) current path + * + * If you uses this method string to path is internally change + * and this object will store new path not only anymore + * @param from source path + * @param to target path + */ +void Rename(const Path & from, const Path & to); + +/** + * @brief Exists Checks if given path exists + * @param path path + * @return true if path exists + */ +bool Exists(const Path & path); + +/** + * @brief Copy file + * + * @param from source path + * @param to target path + */ +void CopyFile(const Path & from, const Path & to); + +/** + * @brief Copy directory recursively + * + * @param from source directory path + * @param to target directory path + */ +void CopyDir(const Path & from, const Path & to); + +Path CreateTempPath(const Path & path); +} + +} + +//TODO: uncomment when user defiend literals are supported +///Path operator"" p(const char * str); + +#endif // PATH_H diff --git a/modules/utils/include/dpl/utils/warp_iri.h b/modules/utils/include/dpl/utils/warp_iri.h new file mode 100644 index 0000000..71773cb --- /dev/null +++ b/modules/utils/include/dpl/utils/warp_iri.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _WARPIRI_H_ +#define _WARPIRI_H_ + +#include + +#include +#include + +class WarpIRI +{ + static const unsigned int UNKNOWN_PORT = 0; + + public: + WarpIRI(); + + void set(const char *iri, + bool domain); + void set(const DPL::String &iristring, + bool domain); + + /* It also checks port and schema */ + bool isSubDomain(const WarpIRI &second) const; + bool isAccessDefinition() const; + bool getSubDomain() const; + + static bool isIRISchemaIgnored(const char *iri); + + bool operator ==(const WarpIRI &other) const + { + return m_domain == other.m_domain && + m_host == other.m_host && + m_schema == other.m_schema && + m_port == other.m_port && + m_isAccessDefinition == other.m_isAccessDefinition && + m_isIRIValid == other.m_isIRIValid; + } + + private: + unsigned int getPort(const DPL::String &schema) const; + + bool m_domain; + std::vector m_host; + DPL::String m_schema; + unsigned int m_port; + bool m_isAccessDefinition; + bool m_isIRIValid; +}; + +#endif // _WarpIRI_H_ diff --git a/modules/utils/include/dpl/utils/widget_version.h b/modules/utils/include/dpl/utils/widget_version.h new file mode 100644 index 0000000..de3d3aa --- /dev/null +++ b/modules/utils/include/dpl/utils/widget_version.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file widget_version.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for widget version + */ +#ifndef WIDGET_VERSION_H +#define WIDGET_VERSION_H + +#include +#include +#include + +/* + * Note: This class also support non-WAC compliant version numbers + * + * WAC Waikiki Beta Release Core Specification: Widget Runtime + * 10 Dec 2010 + * + * WL-3370 The WRT MUST process widget packages as an update when received under + * the following conditions: + * + * - the Widget Id matches the Widget Id of an installed widget + * - the Widget version number is greater (as a compared string) than that of + * the installed widget, or no version + * information was provided for the installed widget + * + * To ensure that a string comparison of widget versions can reliably determine + * which version is an updated widget, + * WAC will mandate a specific version string format for WAC widgets. All + * widgets coming through the WAC channel + * will be required to have version strings in this format. Side-loaded widgets + * may have any format and, in this + * case, there is no requirement that the WRT support version detection for + * update of these widgets. + * + * The widget version format is the rec-version-tag grammar as described in + * [Widget Packaging]: + * + * rec-version-tag = 1*DIGIT "." 1*DIGIT [ "." 1*DIGIT] *[ 1*ALPHA / SP / + * 1*DIGIT ] + * + * Examples of rec-version-tag: + * + * 1.0 + * 1.10.1 beta1 + * 1.02.12 RC1 + * + * WL-3371 The WRT MUST use the following widget version comparison algorithm to + * compare WAC widget version strings: + * + * - prepare the version strings for comparison: + * - all leading zeros are discarded + * - the optional *[ 1*ALPHA / SP / 1*DIGIT ] part, if present, is discarded + * - the resulting numbers are then in the format major.minor[.micro] + * - Version A = Amajor.Aminor[.Amicro] is equal to Version B = + * Bmajor.Bminor[.Bmicro] if and only if: + * - Amajor Bmajor + * - Aminor Bminor + * - both Amicro and Bmicro are present and Amicro == Bmicro; or both Amicro + * and Bmicro are absent. + * - Version A = Amajor.Aminor[.Amicro] is greater than Version B = + * Bmajor.Bminor[.Bmicro] if and only if: + * - Amajor > Bmajor; or + * - Amajor Bmajor && Aminor > Bminor; or + * - Amajor Bmajor && Aminor == Bminor && both Amicro and Bmicro are present + * and Amicro > Bmicro; or Bmicro is absent. + */ +class WidgetVersion +{ + private: + bool m_isWac; + DPL::String m_raw; + + DPL::String m_major; + DPL::String m_minor; + DPL::Optional m_micro; + DPL::Optional m_optional; + + void WacCertify(const DPL::String &major, + const DPL::String &minor, + const DPL::Optional µ, + const DPL::Optional &optional); + + public: + explicit WidgetVersion(const DPL::String &str = DPL::String()); + WidgetVersion(const DPL::String &major, + const DPL::String &minor, + const DPL::Optional µ, + const DPL::Optional &optional); + + bool IsWac() const; + const DPL::String &Raw() const; + + const DPL::String &Major() const; + const DPL::String &Minor() const; + const DPL::Optional &Micro() const; + const DPL::Optional &Optional() const; +}; + +bool operator<(const WidgetVersion &left, + const WidgetVersion &right); +bool operator<=(const WidgetVersion &left, + const WidgetVersion &right); +bool operator>(const WidgetVersion &left, + const WidgetVersion &right); +bool operator>=(const WidgetVersion &left, + const WidgetVersion &right); +bool operator==(const WidgetVersion &left, + const WidgetVersion &right); +bool operator!=(const WidgetVersion &left, + const WidgetVersion &right); +std::ostream & operator<<(std::ostream& stream, + const WidgetVersion& version); + +#endif // WIDGET_VERSION_H diff --git a/modules/utils/include/dpl/utils/wrt_global_settings.h b/modules/utils/include/dpl/utils/wrt_global_settings.h new file mode 100644 index 0000000..14407ae --- /dev/null +++ b/modules/utils/include/dpl/utils/wrt_global_settings.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file wrt_global_settings.h + * @version 0.6 + * @author Pawel Sikorski(p.sikorski@samsung.com) + * @brief Header file for global predefined wrt setting + */ + +#ifndef WRT_COMMON_GLOBAL_SETTINGS_H_ +#define WRT_COMMON_GLOBAL_SETTINGS_H_ + +namespace GlobalSettings { +// Methods for getting test mode environment flag +bool TestModeEnabled(); +bool PopupsTestModeEnabled(); +bool WarpTestModeEnabled(); +bool RoamingTestModeEnabled(); +bool OCSPTestModeEnabled(); +bool CrlTestModeEnabled(); +bool MakeScreenTestModeEnabled(); +bool IsEmulator(); +} + +#endif /* WRT_COMMON_GLOBAL_SETTINGS_H_ */ diff --git a/modules/utils/include/dpl/utils/wrt_utility.h b/modules/utils/include/dpl/utils/wrt_utility.h new file mode 100644 index 0000000..165e167 --- /dev/null +++ b/modules/utils/include/dpl/utils/wrt_utility.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file wrt_utility.h + * @version 0.8 + * @author Janusz Majnert + * @brief Common utility functions + */ + +#ifndef _WRT_UTILITY_H_ +#define _WRT_UTILITY_H_ + +#include + +/** + * Joins two paths into one + * + * @param[out] joined String for storing joined paths + * @param[in] parent String containing the first part of path + * @param[in] child String containing the second part of the path + * + * Data stored in joined before the function call will be replaced with joined + * paths. + */ +void WrtUtilJoinPaths(std::string &joined, + const std::string &parent, + const std::string &child); + +/** + * Creates directories specified by path + * + * @param[in] path Path to create + * @param[in] mode access flags, default to 0755 + * @return true on success, false on failure + * + * Function creates directory specified by path argument and all directories + * leading up to it, if they don't exist. Note that if yout wish to create + * several nested directories, you must make sure that the mode flag allows you + * to write and search the direcotries you create. + */ +bool WrtUtilMakeDir(const std::string &newpath, mode_t mode = 0755); + +/** + * This function removes the directory or file pointed to by path + * + * @param[in] path Path to the file/directory to be deleted + * + * @return true on success, false otherwise + */ +bool WrtUtilRemove(const std::string &path); + +/** + * Checks if path exists and is a regular file + * + * @param[in] path the string representing path to check + * + * @return true if regular file is accessible under path, false otherwise + */ +bool WrtUtilFileExists(const std::string &path); + +/** + * Checks if path exists and is a directory + * + * @param[in] path the string representing path to check + * + * @return true if directory is accessible under path, false otherwise + */ +bool WrtUtilDirExists(const std::string &path); + +#endif //_WRT_UTILITY_H_ + diff --git a/modules/utils/src/bash_utils.cpp b/modules/utils/src/bash_utils.cpp new file mode 100644 index 0000000..1222eda --- /dev/null +++ b/modules/utils/src/bash_utils.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file bash_utils.cpp + * @author Iwanek Tomasz + * @version 1.0 + */ +#include +#include +#include + +#include + +namespace BashUtils { +std::string escape_arg(const std::string & source) +{ + static const std::string special("!$`\\\""); + std::string ret = "\""; + for (std::string::const_iterator iter = source.begin(); + iter != source.end(); + ++iter) + { + if (special.find(*iter) != std::string::npos) { + ret += std::string("\\") + *iter; + } else { + ret += *iter; + } + } + return ret + "\""; +} +} diff --git a/modules/utils/src/folder_size.cpp b/modules/utils/src/folder_size.cpp new file mode 100644 index 0000000..522216a --- /dev/null +++ b/modules/utils/src/folder_size.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * + * @file folder_size.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief Implementation for function calculating directory size + */ +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace Utils { +size_t getFolderSize(const std::string& path) +{ + size_t size = 0; + FTS *fts; + FTSENT *ftsent; + char * const paths[] = { const_cast(path.c_str()), NULL }; + + if ((fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) == NULL) { + //ERROR + int error = errno; + LogWarning(__PRETTY_FUNCTION__ << ": fts_open failed with error: " + << strerror(error)); + return 0; + } + + while ((ftsent = fts_read(fts)) != NULL) { + switch (ftsent->fts_info) { + case FTS_DP: + case FTS_DC: + //directory in postorder and directory causing a loop + break; + case FTS_F: + case FTS_D: + case FTS_NSOK: + case FTS_SL: + case FTS_SLNONE: + case FTS_DEFAULT: + //regular files and other objects that can be counted + size += ftsent->fts_statp->st_size; + break; + case FTS_NS: + case FTS_DOT: + case FTS_DNR: + case FTS_ERR: + default: + LogWarning(__PRETTY_FUNCTION__ + << ": traversal failed on file: " + << ftsent->fts_path + << " with error: " + << strerror(ftsent->fts_errno)); + return 0; + } + } + + if (fts_close(fts) == -1) { + int error = errno; + LogWarning(__PRETTY_FUNCTION__ << ": fts_close failed with error: " + << strerror(error)); + return 0; + } + + return size; +} + +namespace { +#define DECLARE_PREFIX_STRUCT(name) \ + struct Prefix##name \ + { \ + static std::string get() \ + { \ + return std::string(#name); \ + } \ + }; \ + +DECLARE_PREFIX_STRUCT(B) +DECLARE_PREFIX_STRUCT(KB) +DECLARE_PREFIX_STRUCT(MB) +DECLARE_PREFIX_STRUCT(GB) + +#undef DECLARE_PREFIX_STRUCT + +const int stepSize = 1024; +template +struct Pre; + +template +struct Pre +{ + static const double value; + static std::string printSize(double fileSize) + { + if (fileSize >= Pre::value) { + double now = fileSize / Pre::value; + std::ostringstream outputStream; + outputStream.setf(std::ios::fixed, std::ios::floatfield); + outputStream.precision(2); + outputStream << now << Postfix::get(); + return outputStream.str(); + } else { + return Pre::printSize(fileSize); + } + } +}; + +template<> +struct Pre<> +{ + static const double value; + static std::string printSize(double /*fileSize*/) + { + return "0B"; + } +}; + +const double Pre<>::value = 1.0; +template const double Pre:: + value(Pre<>::value * stepSize); + +typedef Pre FolderSizeToStringType; +} //anonymous namespace + +DPL::String fromFileSizeString(size_t fileSize) +{ + std::string output = + FolderSizeToStringType::printSize(static_cast(fileSize)); + return DPL::FromUTF8String(output); +} +} // end of namespace Utils diff --git a/modules/utils/src/mime_type_utils.cpp b/modules/utils/src/mime_type_utils.cpp new file mode 100644 index 0000000..a51df5e --- /dev/null +++ b/modules/utils/src/mime_type_utils.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +#include + +#include + +const std::set& MimeTypeUtils::getMimeTypesSupportedForIcon() +{ + static std::set set; + DPL::String (*s)(const std::string&) = DPL::FromASCIIString; + if (set.empty()) { + set.insert(s("image/gif")); + set.insert(s("image/png")); + set.insert(s("image/vnd.microsoft.icon")); + set.insert(s("image/svg+xml")); + set.insert(s("image/jpeg")); + } + return set; +} + +const std::set& MimeTypeUtils::getMimeTypesSupportedForStartFile() +{ + static std::set set; + DPL::String (*s)(const std::string&) = DPL::FromASCIIString; + if (set.empty()) { + set.insert(s("text/html")); + set.insert(s("application/xhtml+xml")); + set.insert(s("image/svg+xml")); + } + return set; +} + +bool MimeTypeUtils::isMimeTypeSupportedForStartFile(const DPL::String& mimeType) +{ + return getMimeTypesSupportedForStartFile().count(stripMimeParameters( + mimeType)) > 0; +} + +const MimeTypeUtils::FileIdentificationMap& MimeTypeUtils:: + getFileIdentificationMap() +{ + static FileIdentificationMap map; + DPL::String (*s)(const std::string&) = DPL::FromASCIIString; + if (map.empty()) { + map[s(".html")] = s("text/html"); + map[s(".htm")] = s("text/html"); + map[s(".css")] = s("text/css"); + map[s(".js")] = s("application/javascript"); + map[s(".xml")] = s("application/xml"); + map[s(".txt")] = s("text/plain"); + map[s(".wav")] = s("audio/x-wav"); + map[s(".xhtml")] = s("application/xhtml+xml"); + map[s(".xht")] = s("application/xhtml+xml"); + map[s(".gif")] = s("image/gif"); + map[s(".png")] = s("image/png"); + map[s(".ico")] = s("image/vnd.microsoft.icon"); + map[s(".svg")] = s("image/svg+xml"); + map[s(".jpg")] = s("image/jpeg"); + } + return map; +} + +bool MimeTypeUtils::isMimeTypeSupportedForIcon(const DPL::String& mimeType) +{ + return getMimeTypesSupportedForIcon().count(stripMimeParameters(mimeType)) + > 0; +} + +DPL::String MimeTypeUtils::stripMimeParameters(const DPL::String& mimeType) +{ + size_t parametersStart = mimeType.find_first_of(L';'); + if (parametersStart != DPL::String::npos) { + return mimeType.substr(0, parametersStart); + } else { + return mimeType; + } +} + +MimeTypeUtils::MimeAttributes MimeTypeUtils::getMimeAttributes( + const DPL::String& mimeType) +{ + MimeAttributes attributes; + std::vector tokens; + DPL::Tokenize(mimeType, L";=", std::back_inserter(tokens)); + for (unsigned int i = 1; i < tokens.size(); i += 2) { + attributes[tokens[i]] = tokens[i + 1]; + } + return attributes; +} + +bool MimeTypeUtils::isValidIcon(const DPL::String& path) +{ + return getMimeTypesSupportedForIcon().count(identifyFileMimeType(path)) > 0; +} + +bool MimeTypeUtils::isValidStartFile( + const DPL::String& path, + const DPL::OptionalString& + providedMimeType) +{ + DPL::String mimeType = (!!providedMimeType) ? stripMimeParameters( + *providedMimeType) : identifyFileMimeType(path); + return getMimeTypesSupportedForStartFile().count(mimeType) > 0; +} + +DPL::String MimeTypeUtils::getFileNameFromPath(const DPL::String& path) +{ + size_t lastSlashPos = path.find_last_of(L'/'); + return path.substr(lastSlashPos + 1); +} + +DPL::String MimeTypeUtils::identifyFileMimeType(const DPL::String& path) +{ + DPL::String name = getFileNameFromPath(path); //step 4 + + if (name.size() == 0) { + ThrowMsg(Exception::InvalidFileName, "Path should contain a file name."); + } + + size_t lastFullStop = name.find_last_of(L'.'); + if (lastFullStop != 0 && lastFullStop != DPL::String::npos) { //step 5 + DPL::String extension = name.substr(lastFullStop); //step 6 & 7 + if (extension.size() > 0) { //step 8 + //step 9 + std::transform(extension.begin(), extension.end(), + extension.begin(), ::towlower); + FileIdentificationMap::const_iterator it = + getFileIdentificationMap().find(extension); + if (it != getFileIdentificationMap().end()) { + return it->second; + } + } + } + //TODO step 10 - sniff + return DPL::FromASCIIString("application/sniff"); +} diff --git a/modules/utils/src/path.cpp b/modules/utils/src/path.cpp new file mode 100644 index 0000000..0a41837 --- /dev/null +++ b/modules/utils/src/path.cpp @@ -0,0 +1,540 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file path.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + */ + +#include "dpl/utils/path.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace DPL { + +namespace Utils { + +namespace { +const char * const TEMPORARY_PATH_POSTFIX = "temp"; +const mode_t TEMPORARY_PATH_MODE = 0775; +} // namespace + +Path::Iterator::Iterator() //end iterator by default +{ +} + +Path::Iterator::Iterator(const char * str) +{ + m_root = std::shared_ptr(new Path(str)); + m_dir = std::shared_ptr(opendir(str), [](DIR * d){ if(d)closedir(d); }); //custom delete + if(m_dir.get() == NULL) + { + ThrowMsg(NotDirectory, "Not directory"); + } + ReadNext(); +} + +Path::Iterator& Path::Iterator::operator++() +{ + ReadNext(); + return *this; +} + +Path::Iterator Path::Iterator::operator++(int) +{ + Path::Iterator copy(*this); + ReadNext(); + return copy; +} + +void Path::Iterator::ReadNext() +{ + struct dirent * entry = readdir(m_dir.get()); + while(entry && (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0)) + { + entry = readdir(m_dir.get()); + } + if(entry) + { + m_path = std::shared_ptr(new Path(*m_root)); + m_path->Append(entry->d_name); + } + else //transform into end iterator + { + m_path.reset(); + m_dir.reset(); + } +} + +bool Path::Iterator::operator==(const Path::Iterator& rhs) const +{ + if(m_dir.get() == NULL) + { + if(rhs.m_dir.get() == NULL) return true; + else return false; + } + else + { + if(rhs.m_dir.get() == NULL) return false; + } + return *m_path == *rhs.m_path; +} + +bool Path::Iterator::operator!=(const Path::Iterator& rhs) const +{ + return !this->operator==(rhs); +} + +const Path & Path::Iterator::operator*() +{ + return *m_path; +} + +const Path * Path::Iterator::operator->() +{ + return m_path.get(); +} + +Path::Path(const DPL::String & str) +{ + Construct(ToUTF8String(str)); +} + +Path::Path(const std::string & str) +{ + Construct(str); +} + +Path::Path(const char * str) +{ + Construct(std::string(str)); +} + +void Path::Construct(const std::string & src) +{ + if(src.empty()) ThrowMsg(EmptyPath, "Path cannot be empty"); + if(src[0] != '/') + { + DPL::ScopedFree root(getcwd(NULL,0)); + Tokenize(std::string(root.Get()), "\\/", std::inserter(m_parts, m_parts.begin()), true); + } + Tokenize(src, "\\/", std::inserter(m_parts, m_parts.end()), true); +} + +Path::Path() +{ +} + +std::string Path::DirectoryName() const +{ + if(m_parts.empty()) ThrowMsg(InternalError, "Asking DirectoryName for root directory"); + std::string ret = Join(m_parts.begin(), --m_parts.end(), "/"); + return std::string("/") + ret; +} + +std::string Path::Filename() const +{ + if(m_parts.empty()) return ""; + else return m_parts.back(); +} + +std::string Path::Fullpath() const +{ + std::string ret = Join(m_parts.begin(), m_parts.end(), "/"); + return std::string ("/") + ret; +} + +std::string Path::Extension() const +{ + if(m_parts.empty()) return ""; + + const std::string& last = *--m_parts.end(); + + std::string::size_type pos = last.find_last_of("."); + if(pos != std::string::npos) + { + return last.substr(pos + 1); + } + else + { + return ""; + } +} + +//foreach +Path::Iterator Path::begin() const +{ + if(IsDir()) + { + return Iterator(Fullpath().c_str()); + } + else + { + ThrowMsg(NotDirectory, "Cannot iterate not a directory"); + } +} + +Path::Iterator Path::end() const +{ + return Iterator(); +} + +void Path::RootGuard() const +{ + if(m_parts.empty()) Throw(RootDirectoryError); +} + +bool Path::Exists() const +{ + struct stat tmp; + memset(&tmp, 0, sizeof(struct stat)); + return (0 == lstat(Fullpath().c_str(), &tmp)); +} + +bool Path::IsDir() const +{ + struct stat tmp; + memset(&tmp, 0, sizeof(struct stat)); + if (-1 == lstat(Fullpath().c_str(), &tmp)) + { + ThrowMsg(NotExists, DPL::GetErrnoString()); + } + return S_ISDIR(tmp.st_mode); +} + +bool Path::IsFile() const +{ + struct stat tmp; + memset(&tmp, 0, sizeof(struct stat)); + if (-1 == lstat(Fullpath().c_str(), &tmp)) + { + ThrowMsg(NotExists, DPL::GetErrnoString()); + } + return S_ISREG(tmp.st_mode); +} + +bool Path::ExistsAndIsFile() const +{ + bool flag = false; + Try + { + flag = this->IsFile(); + } Catch (Path::NotExists) { + LogPedantic(*this << "is not a file."); + } + return flag; +} + +bool Path::ExistsAndIsDir() const +{ + bool flag = false; + Try + { + flag = this->IsDir(); + } Catch (Path::NotExists) { + LogPedantic(*this << "is not a directory."); + } + return flag; +} + +bool Path::IsSymlink() const +{ + struct stat tmp; + memset(&tmp, 0, sizeof(struct stat)); + if (-1 == lstat(Fullpath().c_str(), &tmp)) + { + ThrowMsg(NotExists, DPL::GetErrnoString()); + } + return S_ISLNK(tmp.st_mode); +} + +bool Path::operator==(const Path & other) const +{ + return m_parts == other.m_parts; +} + +bool Path::operator!=(const Path & other) const +{ + return m_parts != other.m_parts; +} + +Path Path::operator/(const DPL::String& part) const +{ + Path newOne(*this); + newOne.Append(ToUTF8String(part)); + return newOne; +} + +Path Path::operator/(const std::string& part) const +{ + Path newOne(*this); + newOne.Append(part); + return newOne; +} + +Path Path::operator/(const char * part) const +{ + Path newOne(*this); + newOne.Append(std::string(part)); + return newOne; +} + +Path & Path::operator/=(const DPL::String& part) +{ + Append(ToUTF8String(part)); + return *this; +} + +Path & Path::operator/=(const std::string& part) +{ + Append(part); + return *this; +} + +Path & Path::operator/=(const char * part) +{ + Append(std::string(part)); + return *this; +} + +void Path::Append(const std::string& part) +{ + std::vector tokens; + Tokenize(part, "\\/", std::inserter(tokens, tokens.end()), true); + std::copy(tokens.begin(), tokens.end(), std::inserter(m_parts, m_parts.end())); +} + +Path Path::DirectoryPath() const +{ + Path npath; + if(m_parts.empty()) ThrowMsg(InternalError, "Asking DirectoryPath for root directory"); + std::copy(m_parts.begin(), --m_parts.end(), std::back_inserter(npath.m_parts)); + return npath; +} + +std::size_t Path::Size() const +{ + struct stat tmp; + memset(&tmp, 0, sizeof(struct stat)); + if (-1 == lstat(Fullpath().c_str(), &tmp)) + { + ThrowMsg(NotExists, DPL::GetErrnoString()); + } + return tmp.st_size; +} + +bool Path::isSubPath(const Path & other) const +{ + typedef std::vector::const_iterator Iter; + Iter otherIter = other.m_parts.begin(); + for(Iter iter = m_parts.begin(); iter != m_parts.end(); iter++) + { + if(otherIter == other.m_parts.end()) return false; + if(*iter != *otherIter) return false; + otherIter++; + } + return true; +} + +bool Path::hasExtension(const std::string& extension) const +{ + LogPedantic("Looking for extension " << extension); + + if(Extension() == extension) + { + return true; + } + else + { + return false; + } +} + +void MakeDir(const Path & path, mode_t mode) +{ + path.RootGuard(); + if(!WrtUtilMakeDir(path.Fullpath(), mode)) + ThrowMsg(Path::OperationFailed, "Cannot make directory"); +} + +void MakeEmptyFile(const Path & path) +{ + path.RootGuard(); + int ret = 0; + ret = mknod(path.Fullpath().c_str(), S_IFREG, 0); + if(ret != 0) + { + if(errno == EEXIST) + { + ThrowMsg(Path::AlreadyExists, "File already exists: " << path); + } + else + { + ThrowMsg(Path::OperationFailed, "Operation failed"); + } + } +} + +void Remove(const Path & path) +{ + path.RootGuard(); + if(!WrtUtilRemove(path.Fullpath())) ThrowMsg(Path::OperationFailed, "Cannot remove path"); +} + +bool TryRemove(const Path & path) +{ + path.RootGuard(); + return WrtUtilRemove(path.Fullpath()); +} + +void Rename(const Path & from, const Path & to) +{ + from.RootGuard(); + to.RootGuard(); + if(from == to) + { + return; + } + if(0 != rename(from.Fullpath().c_str(), to.Fullpath().c_str())) + { + if(errno == EXDEV) + { + if(from.IsDir()) + { + CopyDir(from, to); + Remove(from); + } + else if(from.IsFile() || from.IsSymlink()) + { + CopyFile(from, to); + Remove(from); + } + else + { + ThrowMsg(Path::OperationFailed, DPL::GetErrnoString()); + } + } + else + { + ThrowMsg(Path::OperationFailed, DPL::GetErrnoString()); + } + } +} + +void CopyFile(const Path & from, const Path & to) +{ + from.RootGuard(); + to.RootGuard(); + Try + { + DPL::FileInput input(from.Fullpath()); + DPL::FileOutput output(to.Fullpath()); + DPL::Copy(&input, &output); + } + Catch(DPL::FileInput::Exception::Base) + { + LogError("File input error"); + ReThrowMsg(DPL::CopyFailed, std::string("File input error") + from.Fullpath()); + } + Catch(DPL::FileOutput::Exception::Base) + { + LogError("File output error"); + ReThrowMsg(DPL::CopyFailed, std::string("File output error") + to.Fullpath()); + } + Catch(DPL::CopyFailed) + { + LogError("File copy error"); + ReThrowMsg(DPL::CopyFailed, std::string("File copy error") + from.Fullpath()); + } +} + +void CopyDir(const Path & from, const Path & to) +{ + from.RootGuard(); + to.RootGuard(); + if(from.isSubPath(to)) + { + ThrowMsg(Path::CannotCopy, "Cannot copy content of directory to it's sub directory"); + } + MakeDir(to); + FOREACH(item, from) + { + if(item->IsDir()) + { + CopyDir(*item, to / item->Filename()); + } + else if(item->IsFile() || item->IsSymlink()) + { + CopyFile(*item, to / item->Filename()); + } + else + { + Throw(Path::OperationFailed); + } + } +} + +Path CreateTempPath(const Path & basePath) +{ + LogDebug("Step: Creating temporary path"); + + // Temporary path + Path tempPath = basePath; + tempPath /= WrtDB::GlobalConfig::GetTmpDirPath(); + + timeval tv; + gettimeofday(&tv, NULL); + unsigned long long nr = (static_cast(tv.tv_sec) * 1000000ULL + static_cast(tv.tv_usec)); + std::stringstream relPath; + relPath << TEMPORARY_PATH_POSTFIX << "_" << nr; + tempPath /= relPath.str(); + + MakeDir(tempPath, TEMPORARY_PATH_MODE); + return tempPath; +} + +bool Exists(const Path & path) +{ + return path.Exists(); +} + +} + +} + +std::ostream & operator<<(std::ostream & str, const DPL::Utils::Path & path) +{ + str << path.Fullpath(); + return str; +} + +//TODO: uncomment when used defiend literals are supported +///DPL::Utils::Path operator""p(const char * str, size_t) +//{ +// return DPL::Utils::Path(str); +//} diff --git a/modules/utils/src/warp_iri.cpp b/modules/utils/src/warp_iri.cpp new file mode 100644 index 0000000..bd8650a --- /dev/null +++ b/modules/utils/src/warp_iri.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file have been implemented in compliance with W3C WARP SPEC. + * but there are some patent issue between W3C WARP SPEC and APPLE. + * so if you want to use this file, refer to the README file in root directory + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +namespace { +// All schemes which are supported by external application should be ignored +// by WARP engine. +// +// Warp specification require from iri to have host element. File protocol +// does not contain host element so it's always denied by warp. +// Unfortunatly all widgets are using file protocol to load its data from +// hard drive. What's why we cannot check any iri with file schema. + +const char *IRI_IGNORED_SCHEME[] = { "file://", "widget://", "app://", "tel:", + "sms:", "smsto:", "mmsto:", "mailto:", "data:", "blob:", + "tizen-service:", 0 }; + +const DPL::String SCHEMA_HTTP = DPL::FromUTF8String("http"); +const DPL::String SCHEMA_HTTPS = DPL::FromUTF8String("https"); +const DPL::String SCHEMA_FTP = DPL::FromUTF8String("ftp"); +} // namespace anonymous + +WarpIRI::WarpIRI() : + m_domain(false), + m_port(UNKNOWN_PORT), + m_isAccessDefinition(false), + m_isIRIValid(false) +{} + +void WarpIRI::set(const char *p_iri, + bool domain) +{ + if (!p_iri) { + m_isAccessDefinition = m_isIRIValid = false; + return; + } + + m_domain = domain; + m_isAccessDefinition = true; + m_isIRIValid = true; + m_host.clear(); + + if (strcmp(p_iri, "*") == 0) { + return; + } + std::unique_ptr iri(iri_parse(p_iri), iri_destroy); + + if (!iri.get()) { + LogError("Error in iri_parse!"); + m_isIRIValid = false; + m_isAccessDefinition = false; + return; + } + + if (iri->scheme == NULL || iri->host == NULL) { + m_isIRIValid = false; + m_isAccessDefinition = false; + return; + } + + // all of this must be NULL in WARP definition + if (iri->user || iri->path || iri->query || iri->anchor) { + m_isAccessDefinition = false; + } + + m_schema = DPL::FromASCIIString(std::string(iri->scheme)); + m_port = static_cast(iri->port); + + if (m_port == 0) { + m_port = getPort(m_schema); + if (m_port == UNKNOWN_PORT) { + m_isAccessDefinition = false; + return; + } + } + + std::string utf8host = iri->host; + std::list hostTokenList; + DPL::Tokenize(utf8host, ".", std::front_inserter(hostTokenList)); + + if (SCHEMA_HTTP == m_schema || SCHEMA_HTTPS == m_schema) { + FOREACH(i, hostTokenList) { + char *output = NULL; + int rc = idna_to_ascii_8z(i->c_str(), + &output, + IDNA_USE_STD3_ASCII_RULES); + + if (IDNA_SUCCESS != rc) { + LogWarning("libidn error: " << rc << " " << + idna_strerror((Idna_rc)rc)); + m_isIRIValid = false; + m_isAccessDefinition = false; + } else { + std::string token(output); + std::transform(token.begin(), + token.end(), + token.begin(), + ::tolower); + m_host.push_back(DPL::FromUTF8String(token)); + } + free(output); + } + } else { + FOREACH(i, hostTokenList){ + m_host.push_back(DPL::FromUTF8String(*i)); + } + } +} + +void WarpIRI::set(const DPL::String &iristring, + bool domain) +{ + set(DPL::ToUTF8String(iristring).c_str(), domain); +} + +unsigned int WarpIRI::getPort(const DPL::String &schema) const +{ + unsigned int port = UNKNOWN_PORT; + if (schema == SCHEMA_HTTP) { + port = 80; + } else if (schema == SCHEMA_HTTPS) { + port = 443; + } else if (schema == SCHEMA_FTP) { + port = 21; + } + return port; +} + +bool WarpIRI::isSubDomain(const WarpIRI &second) const +{ + if (!m_isAccessDefinition || !second.m_isIRIValid) { + return false; + } + if (m_schema != second.m_schema) { + return false; + } + if (m_port != second.m_port) { + return false; + } + + size_t size = m_host.size() < second.m_host.size() ? + m_host.size() : second.m_host.size(); + + if (m_host.size() > second.m_host.size()) { + return false; + } + + if (!m_domain && (m_host.size() != second.m_host.size())) { + return false; + } + + for (size_t i = 0; i < size; ++i) { + if (DPL::StringCompare(m_host[i], second.m_host[i])) { + return false; + } + } + return true; +} + +bool WarpIRI::isAccessDefinition() const +{ + return m_isAccessDefinition; +} + +bool WarpIRI::getSubDomain() const +{ + return m_domain; +} + +bool WarpIRI::isIRISchemaIgnored(const char *iri) +{ + for (int i = 0; IRI_IGNORED_SCHEME[i]; ++i) { + if (0 == + strncmp(iri, IRI_IGNORED_SCHEME[i], + strlen(IRI_IGNORED_SCHEME[i]))) + { + return true; + } + } + return false; +} diff --git a/modules/utils/src/widget_version.cpp b/modules/utils/src/widget_version.cpp new file mode 100644 index 0000000..6ba7933 --- /dev/null +++ b/modules/utils/src/widget_version.cpp @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file widget_version.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for widget version + */ +#include +#include +#include +#include +#include +#include + +namespace // anonymous +{ +size_t WAC_CERTIFY_MANDATORY_PART_LOW_COUNT = 2; +size_t WAC_CERTIFY_MANDATORY_PART_HIGH_COUNT = 3; +size_t WAC_CERTIFY_MANDATORY_PART_MAJOR_INDEX = 0; +size_t WAC_CERTIFY_MANDATORY_PART_MINOR_INDEX = 1; +size_t WAC_CERTIFY_MANDATORY_PART_MICRO_INDEX = 2; +DPL::String::value_type WAC_CERTIFY_MANDATORY_VS_OPTIONAL_SPLIT_CHAR = L' '; +DPL::String::value_type WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR = L'.'; +DPL::String::value_type LEADING_ZERO_CHAR = L'0'; + +// +// [ABNF] +// Augmented BNF for Syntax Specifications: ABNF. RFC5234. D. Crocker and P. +// Overell. January 2008. +// +// ALPHA = %x41-5A / %x61-7A +inline bool IsAlpha(int c) +{ + return (c >= 0x41 && c <= 0x5A) || + (c >= 0x61 && c <= 0x7A); +} + +// DIGIT = %x30-39 +inline bool IsDigit(int c) +{ + return c >= 0x30 && c <= 0x39; +} + +// SP = %x20 +inline bool IsSp(int c) +{ + return c == 0x20; +} + +DPL::String RemoveLeadingZeroes(const DPL::String &str) +{ + Assert(!str.empty()); + + if (str[0] != LEADING_ZERO_CHAR) { + return str; + } + + size_t pos = 0; + + while (pos + 1 < str.size()) { + ++pos; + + if (str[pos] != LEADING_ZERO_CHAR) + break; + } + + return str.substr(pos); +} + +// operator < +bool NumberLessOperator(const DPL::String &left, + const DPL::String &right) +{ + // Assume: No leading zeroes + if (left.size() < right.size()) { + return true; + } + + if (left.size() > right.size()) { + return false; + } + + // Now: left.size() == right.size() + for (ssize_t i = static_cast(left.size()) - 1; i >= 0; --i) { + if (left[i] < right[i]) { + return true; + } + + if (left[i] > right[i]) { + return false; + } + } + + // Equal + return false; +} + +bool WacCertifyNumberString(const DPL::String &str) +{ + for (DPL::String::const_iterator i = str.begin(); i != str.end(); ++i) { + if (!IsDigit(*i)) { + return false; + } + } + + return true; +} + +bool WacCertifyAlphaNumberStringSpace(const DPL::String &str) +{ + for (DPL::String::const_iterator i = str.begin(); i != str.end(); ++i) { + if (!IsDigit(*i) && !IsAlpha(*i) && !IsSp(*i)) { + return false; + } + } + + return true; +} +} // anonymous + +WidgetVersion::WidgetVersion(const DPL::String &str) : + m_isWac(false), + m_raw(str) +{ + LogDebug("Parsing version string: " << str); + + // Split optional an mandatory parts + size_t optionalPartPosition = str.find( + WAC_CERTIFY_MANDATORY_VS_OPTIONAL_SPLIT_CHAR); + + DPL::String mandatoryPart; + DPL::Optional optionalPart; + + if (optionalPartPosition == DPL::String::npos) { + mandatoryPart = str; + } else { + mandatoryPart = str.substr(0, optionalPartPosition); + optionalPart = str.substr(optionalPartPosition + 1, DPL::String::npos); + } + + LogDebug("Mandatory part is: " << mandatoryPart); + LogDebug("Optional part is: " << optionalPart); + + // Split string and construct version + std::vector parts; + DPL::Tokenize(mandatoryPart, + WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR, + std::back_inserter(parts), + false); + + LogDebug("Tokenized mandatory parts: " << parts.size()); + + if (parts.size() != WAC_CERTIFY_MANDATORY_PART_LOW_COUNT && + parts.size() != WAC_CERTIFY_MANDATORY_PART_HIGH_COUNT) + { + return; + } + + DPL::String major; + DPL::String minor; + DPL::Optional micro; + + // Certify for Wac + major = parts[WAC_CERTIFY_MANDATORY_PART_MAJOR_INDEX]; + minor = parts[WAC_CERTIFY_MANDATORY_PART_MINOR_INDEX]; + + if (parts.size() == WAC_CERTIFY_MANDATORY_PART_HIGH_COUNT) { + micro = parts[WAC_CERTIFY_MANDATORY_PART_MICRO_INDEX]; + } + + WacCertify(major, minor, micro, optionalPart); +} + +WidgetVersion::WidgetVersion(const DPL::String &major, + const DPL::String &minor, + const DPL::Optional µ, + const DPL::Optional &optional) : + m_isWac(false) +{ + // Create Raw version + m_raw += major; + m_raw += WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR; + m_raw += minor; + + if (!!micro) { + m_raw += WAC_CERTIFY_MANDATORY_NUMBER_PART_SPLIT_CHAR; + m_raw += *micro; + } + + if (!!optional) { + m_raw += WAC_CERTIFY_MANDATORY_VS_OPTIONAL_SPLIT_CHAR; + m_raw += *optional; + } + + // Certify for Wac + WacCertify(major, minor, micro, optional); +} + +void WidgetVersion::WacCertify(const DPL::String &major, + const DPL::String &minor, + const DPL::Optional µ, + const DPL::Optional &optional) +{ + LogDebug("Certyfing..."); + + LogDebug("Major candidate: " << major); + LogDebug("Minor candidate: " << minor); + LogDebug("Micro candidate: " << micro); + LogDebug("Optional candidate: " << optional); + + // Check strings + if (major.empty() || !WacCertifyNumberString(major)) { + LogDebug("Major version not certified!"); + return; + } + + if (minor.empty() || !WacCertifyNumberString(minor)) { + LogDebug("Minor version not certified!"); + return; + } + + if (!!micro && (micro->empty() || !WacCertifyNumberString(*micro))) { + LogDebug("Microversion not certified!"); + return; + } + + if (!!optional && + (optional->empty() || !WacCertifyAlphaNumberStringSpace(*optional))) + { + LogDebug("Optional version not certified!"); + return; + } + + // OK + m_major = major; + m_minor = minor; + m_micro = micro; + m_optional = optional; + + m_isWac = true; + + LogDebug("Certified."); +} + +bool WidgetVersion::IsWac() const +{ + return m_isWac; +} + +const DPL::String &WidgetVersion::Raw() const +{ + return m_raw; +} + +const DPL::String &WidgetVersion::Major() const +{ + return m_major; +} + +const DPL::String &WidgetVersion::Minor() const +{ + return m_minor; +} + +const DPL::Optional &WidgetVersion::Micro() const +{ + return m_micro; +} + +const DPL::Optional &WidgetVersion::Optional() const +{ + return m_optional; +} + +bool operator<(const WidgetVersion &left, + const WidgetVersion &right) +{ + AssertMsg( + left.IsWac() && right.IsWac(), + "Only WAC version strings are comparable!"); + + if (NumberLessOperator(RemoveLeadingZeroes(left.Major()), + RemoveLeadingZeroes(right.Major()))) + { + return true; + } + if (NumberLessOperator(RemoveLeadingZeroes(right.Major()), + RemoveLeadingZeroes(left.Major()))) + { + return false; + } + + if (NumberLessOperator(RemoveLeadingZeroes(left.Minor()), + RemoveLeadingZeroes(right.Minor()))) + { + return true; + } + if (NumberLessOperator(RemoveLeadingZeroes(right.Minor()), + RemoveLeadingZeroes(left.Minor()))) + { + return false; + } + + if (!!left.Micro() && !!right.Micro() && + NumberLessOperator(RemoveLeadingZeroes(*left.Micro()), + RemoveLeadingZeroes(*right.Micro()))) + { + return true; + } + if (!left.Micro() && !!right.Micro()) { + return true; + } + + return false; +} + +bool operator<=(const WidgetVersion &left, + const WidgetVersion &right) +{ + AssertMsg( + left.IsWac() && right.IsWac(), + "Only WAC version strings are comparable!"); + + return (left == right) || (left < right); +} + +bool operator>(const WidgetVersion &left, + const WidgetVersion &right) +{ + AssertMsg( + left.IsWac() && right.IsWac(), + "Only WAC version strings are comparable!"); + + return !(left <= right); +} + +bool operator>=(const WidgetVersion &left, + const WidgetVersion &right) +{ + AssertMsg( + left.IsWac() && right.IsWac(), + "Only WAC version strings are comparable!"); + + return (left == right) || (left > right); +} + +bool operator==(const WidgetVersion &left, + const WidgetVersion &right) +{ + AssertMsg( + left.IsWac() && right.IsWac(), + "Only WAC version strings are comparable!"); + + //Major are equal + //and + //Minor are equal + //and + //Both Micro exist and are equal + //or both Micro do not exist + return RemoveLeadingZeroes(left.Major()) == + RemoveLeadingZeroes(right.Major()) && + RemoveLeadingZeroes(left.Minor()) == + RemoveLeadingZeroes(right.Minor()) && + ( + (!!left.Micro() && !!right.Micro() && + RemoveLeadingZeroes(*left.Micro()) == + RemoveLeadingZeroes(*right.Micro())) || + (!left.Micro() && !right.Micro()) + ); +} + +bool operator!=(const WidgetVersion &left, + const WidgetVersion &right) +{ + AssertMsg( + left.IsWac() && right.IsWac(), + "Only WAC version strings are comparable!"); + + return !(left == right); +} + +std::ostream & operator<<(std::ostream& stream, + const WidgetVersion& version) +{ + stream << version.Raw(); + return stream; +} diff --git a/modules/utils/src/wrt_global_settings.cpp b/modules/utils/src/wrt_global_settings.cpp new file mode 100644 index 0000000..4f005c5 --- /dev/null +++ b/modules/utils/src/wrt_global_settings.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file wrt_global_settings.cpp + * @version 1.0 + * @author Pawel Sikorski(p.sikorski@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @brief runtime + */ +#include +#include +#include +#include +#include +#include +#include + +namespace GlobalSettings { +namespace { +const int ROAMING_TEST = 0x00000001; +const int POPUPS_TEST = 0x00000002; +const int OCSP_TEST = 0x00000004; +const int WARP_TEST = 0x00000008; +const int CRL_TEST = 0x00000010; +const int SCREEN_SHOT_TEST = 0x00000020; +const int ALL_TEST = (ROAMING_TEST | POPUPS_TEST | OCSP_TEST | WARP_TEST + | CRL_TEST | SCREEN_SHOT_TEST); +const char* WRT_TEST_MODE = "WRT_TEST_MODE"; +const char* MACHINE_NAME_EMUL = "emulated"; // "arch_emulated" +enum MachineType +{ + MACHINE_TYPE_TARGET, + MACHINE_TYPE_EMULATOR, + MACHINE_TYPE_UNKNOWN +}; + +struct Settings { + bool isEmulator; + int testModes; + + Settings() : + isEmulator(false), testModes(0) + {} +}; + +Settings gSettings; + +bool initializeGlobalSettings(); +bool initHelper = initializeGlobalSettings(); + +MachineType getMachineType() +{ + // get current machine name + struct utsname u; + if (0 == uname(&u)) { + if (0 == strlen(u.machine)) { + return MACHINE_TYPE_UNKNOWN; + } else { + // If current machine is emul, + // machine name include "_emulated" + std::string machine = u.machine; + // find "emulated" string in the u.machine + if (std::string::npos != machine.find(MACHINE_NAME_EMUL)) { + return MACHINE_TYPE_EMULATOR; + } else { + return MACHINE_TYPE_TARGET; + } + } + } + + return MACHINE_TYPE_UNKNOWN; +} + +bool initializeGlobalSettings() +{ + (void)initHelper; + + // ignore environment variables if this flag is not set +#ifdef GLOBAL_SETTINGS_CONTROL + char * envStr = getenv(WRT_TEST_MODE); + if (NULL != envStr) { + std::string env = envStr; + int testMode = 0; + if ("1" == env) { + testMode = ALL_TEST; + } else { + std::istringstream str(envStr); + while (std::getline(str, env, '|')) { + if ("popups" == env) { + testMode |= POPUPS_TEST; + } else if ("roaming" == env) { + testMode |= ROAMING_TEST; + } else if ("ocsp" == env) { + testMode |= OCSP_TEST; + } else if ("warp" == env) { + testMode |= WARP_TEST; + } else if ("crl" == env) { + testMode |= CRL_TEST; + } else if ("screen" == env) { + testMode |= SCREEN_SHOT_TEST; + } + } + } + gSettings.testModes = testMode; + } + // TODO other settings initialization + +#endif + gSettings.isEmulator = (MACHINE_TYPE_EMULATOR == getMachineType()); + return false; +} +} // namespace + +bool TestModeEnabled() +{ + return ((gSettings.testModes & ALL_TEST) == ALL_TEST); +} + +bool PopupsTestModeEnabled() +{ + return (gSettings.testModes & POPUPS_TEST); +} +bool WarpTestModeEnabled() +{ + return (gSettings.testModes & WARP_TEST); +} +bool RoamingTestModeEnabled() +{ + return (gSettings.testModes & ROAMING_TEST); +} +bool OCSPTestModeEnabled() +{ + return (gSettings.testModes & OCSP_TEST); +} +bool CrlTestModeEnabled() +{ + return (gSettings.testModes & CRL_TEST); +} +bool MakeScreenTestModeEnabled() +{ + return (gSettings.testModes & SCREEN_SHOT_TEST); +} + +bool IsEmulator() +{ + return gSettings.isEmulator; +} +} // GlobalSettings diff --git a/modules/utils/src/wrt_utility.cpp b/modules/utils/src/wrt_utility.cpp new file mode 100644 index 0000000..44044f2 --- /dev/null +++ b/modules/utils/src/wrt_utility.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file wrt_utility.cpp + * @version 0.8 + * @author Janusz Majnert + * @brief Implementation of some common utility functions + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void WrtUtilJoinPaths(std::string &joined, + const std::string &parent, + const std::string &child) +{ + size_t parent_len = parent.length(); + joined = parent; + joined += child; + //In case someone used windows-style paths + std::replace(joined.begin(), joined.end(), '\\', '/'); + + if (parent_len != 0 && child.length() != 0) { + if (joined[parent_len - 1] != '/' && joined[parent_len] != '/') { + joined.insert(parent_len, "/"); + } else if (joined[parent_len - 1] == '/' && joined[parent_len] == + '/') + { + joined.erase(parent_len, 1); + } + } +} + +bool WrtUtilMakeDir(const std::string &newpath, mode_t mode) +{ + size_t pos = 0; + int error; + + if (newpath.length() == 0) { + return false; + } + + std::string path = newpath; + + if (*(path.rbegin()) != '/') { + path += '/'; + } + + while ((pos = path.find('/', pos + 1)) != std::string::npos) { + if (mkdir(path.substr(0, pos).c_str(), mode) != 0) { + error = errno; + if (error == EEXIST) { + continue; + } + LogWarning(__PRETTY_FUNCTION__ << ": failed to create directory " + << path.substr(0, pos) + << ". Error: " + << strerror(error)); + return false; + } + } + return true; +} + +bool WrtUtilRemove(const std::string &path) +{ + FTS *fts; + FTSENT *ftsent; + bool rv = true; + int error = 0; + char * const paths[] = { const_cast(path.c_str()), NULL }; + + if ((fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) == NULL) { + //ERROR + error = errno; + LogWarning(__PRETTY_FUNCTION__ << ": fts_open failed with error: " + << strerror(error)); + return false; + } + + while ((ftsent = fts_read(fts)) != NULL) { + switch (ftsent->fts_info) { + case FTS_D: + //directory in preorder - do nothing + break; + case FTS_DP: + //directory in postorder - remove + if (rmdir(ftsent->fts_accpath) != 0) { + error = errno; + LogWarning(__PRETTY_FUNCTION__ + << ": rmdir failed with error: " + << strerror(error)); + rv = false; + } + break; + case FTS_DC: + case FTS_F: + case FTS_NSOK: + case FTS_SL: + case FTS_SLNONE: + case FTS_DEFAULT: + //regular files and other objects that can safely be removed + if (unlink(ftsent->fts_accpath) != 0) { + error = errno; + LogWarning(__PRETTY_FUNCTION__ + << ": unlink failed with error: " + << strerror(error)); + rv = false; + } + break; + case FTS_NS: + LogWarning(__PRETTY_FUNCTION__ + << ": couldn't get stat info for file: " + << ftsent->fts_path + << ". The error was: " + << strerror(ftsent->fts_errno)); + rv = false; + break; + case FTS_DOT: + case FTS_DNR: + case FTS_ERR: + default: + LogWarning(__PRETTY_FUNCTION__ + << ": traversal failed with error: " + << strerror(ftsent->fts_errno)); + rv = false; + break; + } + } + + if (fts_close(fts) == -1) { + error = errno; + LogWarning(__PRETTY_FUNCTION__ << ": fts_close failed with error: " + << strerror(error)); + rv = false; + } + return rv; +} + +bool WrtUtilFileExists(const std::string &path) +{ + struct stat tmp; + if (stat(path.c_str(), &tmp) == 0) { + return S_ISREG(tmp.st_mode); + } else { + return false; + } +} + +bool WrtUtilDirExists(const std::string &path) +{ + struct stat tmp; + if (stat(path.c_str(), &tmp) == 0) { + return S_ISDIR(tmp.st_mode); + } else { + return false; + } +} + diff --git a/modules/widget_dao/CMakeLists.txt b/modules/widget_dao/CMakeLists.txt new file mode 100644 index 0000000..543f0a5 --- /dev/null +++ b/modules/widget_dao/CMakeLists.txt @@ -0,0 +1,140 @@ +SET(TARGET_WRT_DAO_DB "Sqlite3DbWRT") + +ADD_CUSTOM_COMMAND( + OUTPUT ${CMAKE_BINARY_DIR}/modules/widget_dao/database_checksum.h + COMMAND ${CMAKE_SOURCE_DIR}/modules/widget_dao/orm/gen_db_md5.sh + ARGS ${CMAKE_BINARY_DIR}/modules/widget_dao/database_checksum.h + ${CMAKE_SOURCE_DIR}/modules/widget_dao/orm/wrt_db + DEPENDS ${CMAKE_SOURCE_DIR}/modules/widget_dao/orm/wrt_db + ${CMAKE_SOURCE_DIR}/modules/widget_dao/orm/gen_db_md5.sh + COMMENT "Generating WRT database checksum" + ) + +ADD_CUSTOM_COMMAND( OUTPUT .wrt.db + COMMAND rm -f ${CMAKE_CURRENT_BINARY_DIR}/.wrt.db + COMMAND gcc -Wall -include ${CMAKE_BINARY_DIR}/modules/widget_dao/database_checksum.h -I${PROJECT_SOURCE_DIR}/modules/db/include -I${PROJECT_SOURCE_DIR}/modules/widget_dao/orm -E ${PROJECT_SOURCE_DIR}/modules/widget_dao/orm/wrt_db_sql_generator.h | grep --invert-match "^#" > ${CMAKE_CURRENT_BINARY_DIR}/wrt_db.sql + COMMAND sqlite3 ${CMAKE_CURRENT_BINARY_DIR}/.wrt.db ".read ${CMAKE_CURRENT_BINARY_DIR}/wrt_db.sql" || rm -f ${CMAKE_CURRENT_BINARY_DIR}/.wrt.db + DEPENDS ${CMAKE_BINARY_DIR}/modules/widget_dao/database_checksum.h ${PROJECT_SOURCE_DIR}/modules/widget_dao/orm/wrt_db_sql_generator.h ${PROJECT_SOURCE_DIR}/modules/widget_dao/orm/wrt_db + ) + +ADD_CUSTOM_COMMAND( OUTPUT .wrt.db-journal + COMMAND touch + ARGS ${CMAKE_CURRENT_BINARY_DIR}/.wrt.db-journal + ) + +ADD_CUSTOM_TARGET(${TARGET_WRT_DAO_DB} ALL DEPENDS .wrt.db .wrt.db-journal) + +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/wrt_db.sql + DESTINATION share/wrt-engine/ + ) + +############################################################################### + +INCLUDE(FindPkgConfig) + +PKG_CHECK_MODULES(WRT_DAO_DEPS + appcore-efl + db-util + dlog + ecore + libxml-2.0 + openssl + REQUIRED) + +set(WRT_DAO_RO_SOURCES + dao/config_parser_data.cpp + dao/common_dao_types.cpp + dao/feature_dao_read_only.cpp + dao/path_builder.cpp + dao/plugin_dao_read_only.cpp + dao/property_dao_read_only.cpp + dao/widget_dao_read_only.cpp + dao/webruntime_database.cpp + dao/WrtDatabase.cpp + dao/widget_dao_types.cpp +) + +set(WRT_DAO_RW_SOURCES + dao/feature_dao.cpp + dao/plugin_dao.cpp + dao/property_dao.cpp + dao/widget_dao.cpp +) + +SET(WRT_DAO_INCLUDE_DIRS + ${PROJECT_SOURCE_DIR}/modules/widget_dao/include + ${PROJECT_SOURCE_DIR}/modules/event/include + ${PROJECT_SOURCE_DIR}/modules/widget_dao/orm + ${PROJECT_SOURCE_DIR}/modules/core/include + ${PROJECT_SOURCE_DIR}/modules/db/include + ${PROJECT_SOURCE_DIR}/modules/log/include + ${PROJECT_SOURCE_DIR}/modules/localization/include +) + +INCLUDE_DIRECTORIES(${WRT_DAO_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(SYSTEM ${WRT_DAO_DEPS_INCLUDE_DIRS}) + +ADD_LIBRARY(${TARGET_WRT_DAO_RO_LIB} SHARED + ${WRT_DAO_RO_SOURCES} +) +SET_TARGET_PROPERTIES(${TARGET_WRT_DAO_RO_LIB} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION}) + +SET_TARGET_PROPERTIES(${TARGET_WRT_DAO_RO_LIB} PROPERTIES + COMPILE_FLAGS -fPIC) + +SET_TARGET_PROPERTIES(${TARGET_WRT_DAO_RO_LIB} PROPERTIES + COMPILE_FLAGS "-include ${CMAKE_BINARY_DIR}/modules/widget_dao/database_checksum.h") + +target_link_libraries(${TARGET_WRT_DAO_RO_LIB} + ${TARGET_DPL_EFL} + ${TARGET_DPL_DB_EFL} + ${WRT_DAO_DEPS_LIBRARIES}) +ADD_DEPENDENCIES(${TARGET_WRT_DAO_RO_LIB} ${TARGET_WRT_DAO_DB}) + +ADD_LIBRARY(${TARGET_WRT_DAO_RW_LIB} SHARED ${WRT_DAO_RW_SOURCES}) + +SET_TARGET_PROPERTIES(${TARGET_WRT_DAO_RW_LIB} PROPERTIES + SOVERSION ${API_VERSION} + VERSION ${VERSION}) + +SET_TARGET_PROPERTIES(${TARGET_WRT_DAO_RW_LIB} PROPERTIES COMPILE_FLAGS -fPIC) + +SET_TARGET_PROPERTIES(${TARGET_WRT_DAO_RW_LIB} PROPERTIES + COMPILE_FLAGS "-include ${CMAKE_BINARY_DIR}/modules/widget_dao/database_checksum.h") + +target_link_libraries(${TARGET_WRT_DAO_RW_LIB} + ${TARGET_WRT_DAO_RO_LIB}) +ADD_DEPENDENCIES(${TARGET_WRT_DAO_RW_LIB} ${TARGET_WRT_DAO_DB}) + +INSTALL(TARGETS ${TARGET_WRT_DAO_RO_LIB} + DESTINATION lib) + +INSTALL(TARGETS ${TARGET_WRT_DAO_RW_LIB} + DESTINATION lib) + +INSTALL(FILES + include/dpl/wrt-dao-ro/config_parser_data.h + include/dpl/wrt-dao-ro/common_dao_types.h + include/dpl/wrt-dao-ro/feature_dao_read_only.h + include/dpl/wrt-dao-ro/feature_model.h + include/dpl/wrt-dao-ro/global_config.h + include/dpl/wrt-dao-ro/path_builder.h + include/dpl/wrt-dao-ro/plugin_dao_read_only.h + include/dpl/wrt-dao-ro/property_dao_read_only.h + include/dpl/wrt-dao-ro/widget_config.h + include/dpl/wrt-dao-ro/widget_dao_read_only.h + include/dpl/wrt-dao-ro/wrt_db_types.h + include/dpl/wrt-dao-ro/WrtDatabase.h + include/dpl/wrt-dao-ro/widget_dao_types.h + DESTINATION include/dpl-efl/dpl/wrt-dao-ro + ) + +INSTALL(FILES + include/dpl/wrt-dao-rw/feature_dao.h + include/dpl/wrt-dao-rw/plugin_dao.h + include/dpl/wrt-dao-rw/property_dao.h + include/dpl/wrt-dao-rw/widget_dao.h + DESTINATION include/dpl-efl/dpl/wrt-dao-rw + ) diff --git a/modules/widget_dao/dao/WrtDatabase.cpp b/modules/widget_dao/dao/WrtDatabase.cpp new file mode 100644 index 0000000..1cf6773 --- /dev/null +++ b/modules/widget_dao/dao/WrtDatabase.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include +#include +#include +#include +#include + +namespace WrtDB { +const char* WrtDatabase::Address() +{ + using namespace WrtDB; + return GlobalConfig::GetWrtDatabaseFilePath(); +} + +DPL::DB::SqlConnection::Flag::Type WrtDatabase::Flags() +{ + return DPL::DB::SqlConnection::Flag::UseLucene; +} + +DPL::DB::ThreadDatabaseSupport WrtDatabase::m_interface( + WrtDatabase::Address(), + WrtDatabase::Flags()); + +void WrtDatabase::attachToThreadRO() +{ + m_interface.AttachToThread(DPL::DB::SqlConnection::Flag::RO); +} + +void WrtDatabase::attachToThreadRW() +{ + m_interface.AttachToThread(DPL::DB::SqlConnection::Flag::RW); +} + +void WrtDatabase::detachFromThread() +{ + m_interface.DetachFromThread(); +} + +DPL::DB::ThreadDatabaseSupport& WrtDatabase::interface() +{ + return m_interface; +} + +bool WrtDatabase::CheckTableExist(const char *name) +{ + return m_interface.CheckTableExist(name); +} +} diff --git a/modules/widget_dao/dao/common_dao_types.cpp b/modules/widget_dao/dao/common_dao_types.cpp new file mode 100644 index 0000000..7c0b8c3 --- /dev/null +++ b/modules/widget_dao/dao/common_dao_types.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file common_dao_types.h + * @author Michal Ciepielski (m.ciepielski@samsung.com) + * @version 1.0 + * @brief This file contains the implementation of common data types for wrtdb + */ +#include +namespace WrtDB {} // namespace WrtDB diff --git a/modules/widget_dao/dao/config_parser_data.cpp b/modules/widget_dao/dao/config_parser_data.cpp new file mode 100644 index 0000000..10d8ca5 --- /dev/null +++ b/modules/widget_dao/dao/config_parser_data.cpp @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file config_parser_data.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#include +#include +#include +#include +#include + +namespace WrtDB { +bool IsSpace(const xmlChar* str); +bool CopyChar(xmlChar* out, xmlChar* in); + +bool IsSpace(const xmlChar* str) +{ + int charlen = xmlUTF8Size(str); + + switch (charlen) { + case 1: + switch (*str) { + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x20: + return true; + + default: + return false; + } + + case 2: + if( *(str) == 0xc2 ){ + switch (*(str + 1)) { + case 0x85: + case 0xa0: + return true; + default: + return false; + } + }else + return false; + case 3: + switch (*str) { + case 0xe1: + { + unsigned char c2 = *(str + 1); + unsigned char c3 = *(str + 2); + if ((c2 == 0x9a && c3 == 0x80) || (c2 == 0xa0 && c3 == 0x8e)) { + return true; + } else { + return false; + } + } + + case 0xe2: + switch (*(str + 1)) { + case 0x80: + switch (*(str + 2)) { + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0xa8: + case 0xa9: + case 0xaf: + return true; + default: + return false; + } + case 0x81: + if (*(str + 2) == 0x9f) { + return true; + } else { + return false; + } + + default: + return false; + } + case 0xe3: + if (*(str + 1) == 0x80 && *(str + 2) == 0x80) { + return true; + } else { + return false; + } + + default: + return false; + } + + default: + return false; + } +} + +bool CopyChar(xmlChar* out, + xmlChar* in) +{ + int size = xmlUTF8Size(in); + switch (size) { + case 6: + out[5] = in[5]; + case 5: + out[4] = in[4]; + case 4: + out[3] = in[3]; + case 3: + out[2] = in[2]; + case 2: + out[1] = in[1]; + case 1: + out[0] = in[0]; + return true; + + default: + return false; + } +} + +//TODO temporary fix until commits the rewrite of this functionality. +void NormalizeString(DPL::String& str) +{ + DPL::Optional opt = str; + NormalizeString(opt); + str = *opt; +} + +void NormalizeString (DPL::Optional& txt, bool isTrimSpace) +{ + if (!!txt) { + std::string tmp = DPL::ToUTF8String(*txt); + const xmlChar* str = reinterpret_cast(tmp.c_str()); + if (!xmlCheckUTF8(str)) { + LogError("Not valid UTF8"); + return; + } + + int i = 0; + xmlChar* c; + while ((c = const_cast(xmlUTF8Strpos(str, i))) != NULL) { + if (!IsSpace(c)) { + break; + } + ++i; + } + + xmlChar* tmpnew = xmlUTF8Strndup(c, xmlUTF8Strlen(c) + 1); + bool first = false; + xmlChar* s = tmpnew; + while ((c = const_cast(xmlUTF8Strpos(str, i))) != NULL) { + if (IsSpace(c)) { + first = true; + ++i; + } else { + if (c[0] == 0x0) { + break; + } + if (first && !isTrimSpace) { + xmlChar space[6] = { 0x20 }; + CopyChar(s, space); + s += xmlUTF8Size(s); + first = false; + } + CopyChar(s, c); + s += xmlUTF8Size(s); + ++i; + } + } + s[0] = 0x0; + txt = DPL::FromUTF8String(reinterpret_cast(tmpnew)); + xmlFree(tmpnew); + } +} + +void NormalizeAndTrimSpaceString(DPL::OptionalString& txt) +{ + NormalizeString(txt, true); +} + +bool ConfigParserData::Feature::operator==(const Feature& other) const +{ + return name == other.name; +} + +bool ConfigParserData::Feature::operator!=(const Feature& other) const +{ + return name != other.name; +} + +bool ConfigParserData::Feature::operator >(const Feature& other) const +{ + return name > other.name; +} + +bool ConfigParserData::Feature::operator>=(const Feature& other) const +{ + return name >= other.name; +} + +bool ConfigParserData::Feature::operator <(const Feature& other) const +{ + return name < other.name; +} + +bool ConfigParserData::Feature::operator<=(const Feature& other) const +{ + return name <= other.name; +} + +bool ConfigParserData::Privilege::operator==(const Privilege& other) const +{ + return name == other.name; +} + +bool ConfigParserData::Privilege::operator!=(const Privilege& other) const +{ + return name != other.name; +} + +bool ConfigParserData::Privilege::operator >(const Privilege& other) const +{ + return name > other.name; +} + +bool ConfigParserData::Privilege::operator>=(const Privilege& other) const +{ + return name >= other.name; +} + +bool ConfigParserData::Privilege::operator <(const Privilege& other) const +{ + return name < other.name; +} + +bool ConfigParserData::Privilege::operator<=(const Privilege& other) const +{ + return name <= other.name; +} + +bool ConfigParserData::Icon::operator==(const Icon& other) const +{ + return src == other.src && isSmall == other.isSmall; +} + +bool ConfigParserData::Icon::operator!=(const Icon& other) const +{ + return src != other.src || isSmall != other.isSmall; +} + +bool ConfigParserData::Icon::operator >(const Icon& other) const +{ + return src > other.src; +} + +bool ConfigParserData::Icon::operator>=(const Icon& other) const +{ + return operator >(other) || operator==(other); +} + +bool ConfigParserData::Icon::operator <(const Icon& other) const +{ + return src < other.src; +} + +bool ConfigParserData::Icon::operator<=(const Icon& other) const +{ + return operator<(other) || operator==(other); +} + +bool ConfigParserData::Preference::operator==(const Preference& other) const +{ + return name == other.name; +} + +bool ConfigParserData::Preference::operator!=(const Preference& other) const +{ + return name != other.name; +} + +bool ConfigParserData::Preference::operator >(const Preference& other) const +{ + return name > other.name; +} + +bool ConfigParserData::Preference::operator>=(const Preference& other) const +{ + return name >= other.name; +} + +bool ConfigParserData::Preference::operator <(const Preference& other) const +{ + return name < other.name; +} + +bool ConfigParserData::Preference::operator<=(const Preference& other) const +{ + return name <= other.name; +} + +bool ConfigParserData::AccessInfo::operator== (const AccessInfo& info) const +{ + return m_strIRI == info.m_strIRI && m_bSubDomainAccess == + info.m_bSubDomainAccess; +} + +bool ConfigParserData::AccessInfo::operator!= (const AccessInfo& info) const +{ + return m_strIRI != info.m_strIRI || m_bSubDomainAccess != + info.m_bSubDomainAccess; +} + +bool ConfigParserData::AccessInfo::operator <(const AccessInfo& info) const +{ + if (m_strIRI == info.m_strIRI) { + return m_bSubDomainAccess < info.m_bSubDomainAccess; + } else { + return m_strIRI < info.m_strIRI; + } +} + +bool ConfigParserData::Setting::operator==(const Setting& other) const +{ + return m_name == other.m_name && + m_value == other.m_value; +} + +bool ConfigParserData::Setting::operator!=(const Setting& other) const +{ + return m_name != other.m_name || + m_value != other.m_value; +} + +bool ConfigParserData::Setting::operator >(const Setting& other) const +{ + return m_name > other.m_name; +} + +bool ConfigParserData::Setting::operator>=(const Setting& other) const +{ + return m_name >= other.m_name; +} + +bool ConfigParserData::Setting::operator <(const Setting& other) const +{ + return m_name < other.m_name; +} + +bool ConfigParserData::Setting::operator<=(const Setting& other) const +{ + return m_name <= other.m_name; +} + +bool ConfigParserData::AppControlInfo::operator== (const AppControlInfo& info) const +{ + return m_src == info.m_src && + m_operation == info.m_operation && + m_uriList == info.m_uriList && + m_mimeList == info.m_mimeList && + m_disposition == info.m_disposition; +} + +bool ConfigParserData::AppControlInfo::operator!= (const AppControlInfo& info) const +{ + return m_src != info.m_src || + m_operation != info.m_operation || + m_uriList != info.m_uriList || + m_mimeList != info.m_mimeList || + m_disposition != info.m_disposition; +} + +bool ConfigParserData::LiveboxInfo::operator==(const LiveboxInfo& other) const +{ + return m_liveboxId == other.m_liveboxId && + m_autoLaunch == other.m_autoLaunch && + m_updatePeriod == other.m_updatePeriod && + m_primary == other.m_primary && + m_label == other.m_label && + m_icon == other.m_icon; +} + +bool ConfigParserData::LiveboxInfo::operator!=(const LiveboxInfo& other) const +{ + return !(*this == other); +} + +bool ConfigParserData::Metadata::operator== (const Metadata& other) const +{ + return key == other.key && value == other.value; +} + +bool ConfigParserData::Metadata::operator!= (const Metadata& other) const +{ + return key != other.key || value != other.value; +} +} // namespace WrtDB diff --git a/modules/widget_dao/dao/feature_dao.cpp b/modules/widget_dao/dao/feature_dao.cpp new file mode 100644 index 0000000..15cd23f --- /dev/null +++ b/modules/widget_dao/dao/feature_dao.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the definition of feature dao class. + * + * @file widget_dao.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the definition of feature configuration. + */ +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +namespace FeatureDAO { +FeatureHandle RegisterFeature(const PluginMetafileData::Feature &feature, + const DbPluginHandle pluginHandle) +{ + Try + { + LogDebug("Registering Feature " << feature.m_name); + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + + if (FeatureDAOReadOnly::isFeatureInstalled(feature.m_name)) { + LogError(" >> Feature " << feature.m_name << + " is already registered."); + transaction.Commit(); + return -1; + } + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + //register feature + { + LogDebug(" |-- Registering feature " << feature.m_name); + + FeaturesList::Row row; + row.Set_FeatureName(DPL::FromUTF8String(feature.m_name)); + row.Set_PluginPropertiesId(pluginHandle); + + WRT_DB_INSERT(insert, FeaturesList, &WrtDatabase::interface()) + insert->Values(row); + insert->Execute(); + } + + FeatureHandle featureHandle = + FeatureDAOReadOnly(feature.m_name).GetFeatureHandle(); + + //register device capabilities + // Device Capabilities is unused in current version + FOREACH(itdev, feature.m_deviceCapabilities) + { + int deviceCapID; + + if (FeatureDAOReadOnly::isDeviceCapabilityInstalled(*itdev)) { + LogDebug(" | |--DeviceCap " << *itdev << + " already installed!"); + + WRT_DB_SELECT(select, + DeviceCapabilities, + &WrtDatabase::interface()) + + select->Where(Equals( + DPL::FromUTF8String(*itdev))); + + deviceCapID = + select->GetSingleValue(); + } else { + LogDebug(" | |--Register DeviceCap: " << *itdev); + + DeviceCapabilities::Row row; + row.Set_DeviceCapName(DPL::FromUTF8String(*itdev)); + + WRT_DB_INSERT(insert, + DeviceCapabilities, + &WrtDatabase::interface()) + insert->Values(row); + deviceCapID = static_cast(insert->Execute()); + } + + FeatureDeviceCapProxy::Row row; + row.Set_FeatureUUID(featureHandle); + row.Set_DeviceCapID(deviceCapID); + + WRT_DB_INSERT(insert, + FeatureDeviceCapProxy, + &WrtDatabase::interface()) + insert->Values(row); + insert->Execute(); + } + + transaction.Commit(); + + return featureHandle; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during Registering Feature"); + } +} + +void UnregisterFeature(FeatureHandle featureHandle) +{ + Try + { + LogDebug("Unregistering Feature " << featureHandle); + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + + if (!FeatureDAOReadOnly::isFeatureInstalled(featureHandle)) { + LogError("Feature handle is invalid"); + return; + } + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + // Unregister DeviceCapabilities + FeatureDAOReadOnly::DeviceCapabilitiesList capabilitiesList = + FeatureDAOReadOnly(featureHandle).GetDeviceCapabilities(); + + FOREACH(it, capabilitiesList) { + WRT_DB_DELETE(del, DeviceCapabilities, &WrtDatabase::interface()) + del->Where( + Equals( + DPL::FromUTF8String(*it))); + del->Execute(); + } + + // Unregister Feature + WRT_DB_DELETE(del, FeaturesList, &WrtDatabase::interface()) + del->Where(Equals(featureHandle)); + del->Execute(); + transaction.Commit(); + + return; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Fail to unregister Feature"); + } +} +} // namespace FeatureDAO +} // namespace WrtDB diff --git a/modules/widget_dao/dao/feature_dao_read_only.cpp b/modules/widget_dao/dao/feature_dao_read_only.cpp new file mode 100644 index 0000000..ee188bd --- /dev/null +++ b/modules/widget_dao/dao/feature_dao_read_only.cpp @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file feature_dao_read_only.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the implementation of feature dao read only + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +FeatureDAOReadOnly::FeatureDAOReadOnly(FeatureHandle featureHandle) : + m_featureHandle(featureHandle) +{ + if (!isFeatureInstalled(m_featureHandle)) { + std::ostringstream exc; + exc << "Feature " << m_featureHandle << " not installed."; + LogError(exc.str()); + ThrowMsg(FeatureDAOReadOnly::Exception::FeatureNotExist, exc.str()); + } +} + +FeatureDAOReadOnly::FeatureDAOReadOnly(const std::string &featureName) +{ + LogDebug("FeatureDAOReadOnly ( " << featureName << " )"); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals( + DPL::FromUTF8String(featureName))); + + m_featureHandle = select->GetSingleValue(); + LogDebug(" >> FeatureHandle retrieved: " << m_featureHandle); + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during creating FeatureDAOReadOnly"); + } +} + +#define GET_PLUGIN_DATA(func) \ + Try { \ + DPL::DB::ORM::wrt::ScopedTransaction transaction( \ + &WrtDatabase::interface()); \ + LogDebug(#func << ". FeatureHandle: " << m_featureHandle); \ + std::string ret = PluginDAOReadOnly(GetPluginHandle()).func(); \ + transaction.Commit(); \ + return ret; \ + } \ + Catch(DPL::DB::SqlConnection::Exception::Base) { \ + std::ostringstream failure("Failure during "); \ + failure << #func; \ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, \ + failure.str()); \ + } + +std::string FeatureDAOReadOnly::GetLibraryPath() const +{ + GET_PLUGIN_DATA(getLibraryPath) +} + +std::string FeatureDAOReadOnly::GetLibraryName() const +{ + GET_PLUGIN_DATA(getLibraryName) +} + +#undef GET_PLUGIN_DATA + +FeatureHandle FeatureDAOReadOnly::GetFeatureHandle() const +{ + return m_featureHandle; +} + +std::string FeatureDAOReadOnly::GetName() const +{ + LogDebug("Getting Feature Name. Handle: " << m_featureHandle); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals(m_featureHandle)); + + std::string ret = DPL::ToUTF8String( + select->GetSingleValue< FeaturesList::FeatureName>()); + + LogDebug(" >> Feature name: " << ret); + return ret; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting GetName"); + } +} + +DbPluginHandle FeatureDAOReadOnly::GetPluginHandle() const +{ + LogDebug("Getting Plugin handle. FHandle: " << m_featureHandle); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals(m_featureHandle)); + + DbPluginHandle pluginHandle = + select->GetSingleValue< FeaturesList::PluginPropertiesId>(); + + LogDebug(" >> Plugin Handle: " << pluginHandle); + return pluginHandle; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting Plugin Handle"); + } +} + +FeatureHandleList FeatureDAOReadOnly::GetHandleList() +{ + LogDebug("Getting FeatureHandle list."); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + + FeatureHandleList ret = + select->GetValueList(); + + std::ostringstream handles; + FOREACH(it, ret) + handles << *it << " "; + LogDebug(" >> FeatureHandle list retrieved: (" << handles << ")"); + + return ret; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting FeatureHandle list"); + } +} + +bool FeatureDAOReadOnly::isFeatureInstalled(const std::string &featureName) +{ + LogDebug("Check if Feature is installed. Name: " << featureName); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals( + DPL::FromUTF8String(featureName))); + + FeaturesList::Select::RowList rows = select->GetRowList(); + + bool flag = !rows.empty(); + LogDebug(" >> Feature " << featureName << + (flag ? " found." : " not found.")); + + return flag; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during checking if Feature is installed"); + } +} + +bool FeatureDAOReadOnly::isFeatureInstalled(FeatureHandle handle) +{ + LogDebug("Check if Feature is installed. Handle: " << handle); + Try + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals(handle)); + + FeaturesList::Select::RowList rows = select->GetRowList(); + + bool flag = !rows.empty(); + LogDebug(" >> Feature " << handle << + (flag ? " found." : " not found.")); + + return flag; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during checking if Feature is installed"); + } +} + +bool FeatureDAOReadOnly::isDeviceCapabilityInstalled( + const std::string &deviceCapName) +{ + LogDebug("Check if DeviceCap is installed. Name: " << deviceCapName); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, DeviceCapabilities, &WrtDatabase::interface()) + select->Where(Equals( + DPL::FromUTF8String(deviceCapName))); + + DeviceCapabilities::Select::RowList rows = select->GetRowList(); + + bool flag = !rows.empty(); + LogDebug(" >> Device Cap " << deviceCapName << + (flag ? "found." : "not found.")); + + return flag; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during checking if DeviceCap is installed"); + } +} + +FeatureDAOReadOnly::DeviceCapabilitiesList +FeatureDAOReadOnly::GetDeviceCapabilities() const +{ + Try { + LogDebug("Get DeviceCap. FeatureHandle: " << m_featureHandle); + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(selectDevCP, + FeatureDeviceCapProxy, + &WrtDatabase::interface()) + selectDevCP->Where(Equals( + m_featureHandle)); + + DeviceCapabilitiesList devCap; + + std::list deviceIDs = + selectDevCP->GetValueList(); + FOREACH(devCId, deviceIDs) + { + WRT_DB_SELECT(selectDevC, + DeviceCapabilities, + &WrtDatabase::interface()) + selectDevC->Where(Equals(*devCId)); + + DPL::String devNames = + selectDevC->GetSingleValue(); + + devCap.insert(DPL::ToUTF8String(devNames)); + } + + transaction.Commit(); + return devCap; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting DeviceCapabilities names"); + } +} + +FeatureHandleListPtr FeatureDAOReadOnly::GetFeatureHandleListForPlugin( + DbPluginHandle pluginHandle) +{ + LogDebug("Getting FeatureHandle list for pluginHandle: " << pluginHandle); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals(pluginHandle)); + + FeatureHandleListPtr handles(new FeatureHandleList); + FeatureHandleList ret = + select->GetValueList(); + + FOREACH(it, ret) + { + LogDebug("feature handle: " << *it); + handles->push_back(*it); + } + + return handles; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg( + FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting FeatureHandle Set for plugin handle"); + } +} + +FeatureDAOReadOnly::NameMap +FeatureDAOReadOnly::GetNames() +{ + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + + NameMap nameMap; + + FeaturesList::Select::RowList rows = select->GetRowList(); + FOREACH(rowIt, rows) + { + nameMap.insert(std::pair(rowIt->Get_FeatureUUID(), + DPL::ToUTF8String(rowIt-> + Get_FeatureName()))); + } + + return nameMap; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting GetNames"); + } +} + +FeatureDAOReadOnly::DeviceCapabilitiesMap +FeatureDAOReadOnly::GetDevCapWithFeatureHandle() +{ + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + DECLARE_COLUMN_TYPE_LIST() + SELECTED_COLUMN(FeatureDeviceCapProxy, FeatureUUID) + SELECTED_COLUMN(DeviceCapabilities, DeviceCapName) + DECLARE_COLUMN_TYPE_LIST_END(DevCapNameList) + + WRT_DB_SELECT(select, FeatureDeviceCapProxy, &WrtDatabase::interface()) + select->Join(Equal()); + + DeviceCapabilitiesMap devCap; + + std::list< CustomRow > rowList = + select->GetCustomRowList< DevCapNameList, CustomRow >(); + FOREACH(rowIt, rowList) + { + FeatureHandle featureHandle = + (*rowIt).GetColumnData(); + std::string devName = + DPL::ToUTF8String((*rowIt).GetColumnData()); + devCap.insert(std::pair(featureHandle, + devName)); + } + + return devCap; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting DeviceCapabilities names"); + } +} + +DeviceCapabilitySet FeatureDAOReadOnly::GetDeviceCapability( + const DPL::String &apifeature) +{ + // This could be done with one simply sql query but support for join is + // needed in orm. + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + int featureUUID; + FeatureDeviceCapProxy::Select::RowList rows; + DeviceCapabilitySet result; + + { + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(Equals(apifeature)); + featureUUID = select->GetSingleValue(); + } + + { + WRT_DB_SELECT(select, + FeatureDeviceCapProxy, + &WrtDatabase::interface()) + select->Where(Equals( + featureUUID)); + rows = select->GetRowList(); + } + + FOREACH(it, rows){ + WRT_DB_SELECT(select, DeviceCapabilities, &WrtDatabase::interface()) + select->Where(Equals( + it->Get_DeviceCapID())); + result.insert(select-> + GetSingleValue()); + } + + return result; + } Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failed to get device capability"); + } +} + +FeatureDAOReadOnly::FeatureMap +FeatureDAOReadOnly::GetFeatures(const std::list& featureNames) +{ + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + std::set nameList; + FOREACH(nm, featureNames) { + nameList.insert(DPL::FromUTF8String(*nm)); + } + + WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface()) + select->Where(In(nameList)); + + FeatureMap featureMap; + FeatureData featureData; + FeaturesList::Select::RowList rows = select->GetRowList(); + FOREACH(rowIt, rows) { + featureData.featureName = DPL::ToUTF8String( + rowIt->Get_FeatureName()); + featureData.pluginHandle = rowIt->Get_PluginPropertiesId(); + featureMap.insert(std::pair( + rowIt->Get_FeatureUUID(), featureData)); + } + + return featureMap; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError, + "Failure during getting GetFeatures"); + } +} +} // namespace WrtDB diff --git a/modules/widget_dao/dao/path_builder.cpp b/modules/widget_dao/dao/path_builder.cpp new file mode 100644 index 0000000..ab55476 --- /dev/null +++ b/modules/widget_dao/dao/path_builder.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file PathBuilder.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Implementation file for PathBuilde class. + */ +#include +#include +#include + +namespace WrtDB { +namespace { +const char PATH_SEPARATOR = '/'; +} + +class PathBuilderImpl : DPL::Noncopyable +{ + public: + PathBuilderImpl() + {} + + explicit PathBuilderImpl(const std::string& path) : + m_stream(path, std::ios_base::app) + {} + + void Append(const std::string& path) + { + // TODO Check additionally if last char is not separator. + if (m_stream.tellp() > 0) { + m_stream << PATH_SEPARATOR; + } + m_stream << path; + } + + void Concat(const std::string& arg) + { + m_stream << arg; + } + + void Concat(int arg) + { + m_stream << arg; + } + + void Reset() + { + m_stream.clear(); + m_stream.str(""); + } + + bool Empty() + { + return (m_stream.tellp() == 0); + } + + std::string GetFullPath() const + { + return m_stream.str(); + } + + private: + std::ostringstream m_stream; +}; + +PathBuilder::PathBuilder() : m_impl(new PathBuilderImpl()) +{} + +PathBuilder::PathBuilder(const std::string& path) : + m_impl(new PathBuilderImpl(path)) +{} + +PathBuilder::~PathBuilder() +{ + delete m_impl; +} + +PathBuilder& PathBuilder::Append(const std::string& path) +{ + m_impl->Append(path); + return *this; +} + +PathBuilder& PathBuilder::Concat(const std::string& arg) +{ + m_impl->Concat(arg); + return *this; +} + +PathBuilder& PathBuilder::Concat(int arg) +{ + m_impl->Concat(arg); + return *this; +} + +PathBuilder& PathBuilder::Reset() +{ + m_impl->Reset(); + return *this; +} + +bool PathBuilder::Empty() const +{ + return m_impl->Empty(); +} + +std::string PathBuilder::GetFullPath() const +{ + return m_impl->GetFullPath(); +} +} // namespace WrtDB diff --git a/modules/widget_dao/dao/plugin_dao.cpp b/modules/widget_dao/dao/plugin_dao.cpp new file mode 100644 index 0000000..5b899c3 --- /dev/null +++ b/modules/widget_dao/dao/plugin_dao.cpp @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file plugin_dao.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @author Grzegorz Krawczyk (g.krawczyk@samsung.com) + * @version 1.0 + * @brief This file contains the definition of plugin dao class. + */ +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +PluginDAO::PluginDAO(DbPluginHandle pluginHandle) : + PluginDAOReadOnly(pluginHandle) +{} + +PluginDAO::PluginDAO(const std::string &libraryName) : + PluginDAOReadOnly(libraryName) +{} + +DbPluginHandle PluginDAO::registerPlugin(const PluginMetafileData& metafile, + const std::string& pluginPath) +{ + LogDebug("Registering plugin. Path: " << pluginPath); + + Try { + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + DbPluginHandle handle; + + if (isPluginInstalled(metafile.m_libraryName)) { + handle = PluginDAO(metafile.m_libraryName).getPluginHandle(); + LogDebug(" >> Library " << metafile.m_libraryName << + " is already registered. Handle: " << handle); + } else { + LogDebug("Register Plugin: " << metafile.m_libraryName); + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + typedef PluginProperties::Row PluginPropertiesRow; + + PluginPropertiesRow row; + row.Set_PluginLibraryName( + DPL::FromUTF8String(metafile.m_libraryName)); + row.Set_InstallationState(INSTALLATION_IN_PROGRESS); + row.Set_PluginLibraryPath( + DPL::FromUTF8String(pluginPath)); + + WRT_DB_INSERT(insert, PluginProperties, &WrtDatabase::interface()) + insert->Values(row); + handle = static_cast(insert->Execute()); + LogDebug(" >> Plugin Registered. Handle: " << handle); + } + transaction.Commit(); + return handle; + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + ReThrowMsg(PluginDAO::Exception::DatabaseError, + "Failed in RegisterPlugin"); + } +} + +void PluginDAO::registerPluginImplementedObject(const std::string& objectName, + DbPluginHandle pluginHandle) +{ + LogDebug("Registering plugin object: " << objectName); + + Try { + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + + LogDebug("Register Object: " << objectName); + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + typedef PluginImplementedObjects::Row PluginObjectsRow; + + PluginObjectsRow row; + row.Set_PluginObject(DPL::FromUTF8String(objectName)); + row.Set_PluginPropertiesId(pluginHandle); + + WRT_DB_INSERT(insert, PluginImplementedObjects, &WrtDatabase::interface()) + insert->Values(row); + insert->Execute(); + transaction.Commit(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + ReThrowMsg(PluginDAO::Exception::DatabaseError, + "Failed in RegisterPluginObject"); + } +} + +void PluginDAO::registerPluginRequiredObject(const std::string& objectName, + DbPluginHandle pluginHandle) +{ + LogDebug("Registering plugin object: " << objectName); + + Try { + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + + LogDebug("Register Object: " << objectName); + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + typedef PluginRequiredObjects::Row PluginObjectsRow; + + PluginObjectsRow row; + row.Set_PluginPropertiesId(pluginHandle); + row.Set_PluginObject(DPL::FromUTF8String(objectName)); + + WRT_DB_INSERT(insert, PluginRequiredObjects, &WrtDatabase::interface()) + insert->Values(row); + insert->Execute(); + transaction.Commit(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + ReThrowMsg(PluginDAO::Exception::DatabaseError, + "Failed in RegisterPluginObject"); + } +} + +void PluginDAO::registerPluginLibrariesDependencies( + DbPluginHandle pluginHandle, + const PluginHandleSetPtr& dependencies) +{ + LogDebug("Registering plugin library dependencies: " << pluginHandle); + + Try { + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + typedef PluginDependencies::Row PluginDependeciesRow; + PluginDependeciesRow row; + + FOREACH(it, *dependencies) + { + row.Set_PluginPropertiesId(pluginHandle); + row.Set_RequiredPluginPropertiesId(*it); + + WRT_DB_INSERT(insert, PluginDependencies, &WrtDatabase::interface()) + insert->Values(row); + insert->Execute(); + transaction.Commit(); + } + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + ReThrowMsg(PluginDAO::Exception::DatabaseError, + "Failed in RegisterPluginObject"); + } +} + +void PluginDAO::setPluginInstallationStatus(DbPluginHandle pluginHandle, + PluginInstallationState state) +{ + Try { + LogDebug( + "Set installation state: " << state << " handle " << pluginHandle); + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + ScopedTransaction transaction(&WrtDatabase::interface()); + + typedef wrt::PluginProperties::Row PluginPropertiesRow; + + PluginPropertiesRow row; + row.Set_InstallationState(state); + + WRT_DB_UPDATE(update, PluginProperties, &WrtDatabase::interface()) + update->Where( + Equals(pluginHandle)); + + update->Values(row); + update->Execute(); + transaction.Commit(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + ReThrowMsg(PluginDAO::Exception::DatabaseError, + "Failed in RegisterLibraryDependencies"); + } +} + +void PluginDAO::unregisterPlugin(DbPluginHandle pluginHandle) +{ + LogDebug("unregisterPlugin plugin. Handle: " << pluginHandle); + + Try { + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + + if (!isPluginInstalled(pluginHandle)) { + LogDebug("PluginHandle is invalid. Handle: " << pluginHandle); + return; + } else { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_DELETE(del, PluginProperties, &WrtDatabase::interface()) + del->Where( + Equals(pluginHandle)); + del->Execute(); + + transaction.Commit(); + LogDebug(" >> Plugin Unregistered. Handle: " << pluginHandle); + } + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + ReThrowMsg(PluginDAO::Exception::DatabaseError, + "Failed in UnregisterPlugin"); + } +} +} // namespace WrtDB diff --git a/modules/widget_dao/dao/plugin_dao_read_only.cpp b/modules/widget_dao/dao/plugin_dao_read_only.cpp new file mode 100644 index 0000000..a90e013 --- /dev/null +++ b/modules/widget_dao/dao/plugin_dao_read_only.cpp @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file plugin_dao_read_only.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the implementation of plugin dao read only + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +namespace { +typedef DPL::DB::ORM::wrt::PluginProperties::Row PluginRow; + +PluginRow getPluginRow(DbPluginHandle pluginHandle) +{ + LogDebug("Getting plugin row. Handle: " << pluginHandle); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where(Equals( + pluginHandle)); + + PluginProperties::Select::RowList rows = select->GetRowList(); + if (rows.empty()) { + ThrowMsg(PluginDAOReadOnly::Exception::PluginNotExist, + "Cannot find plugin. Handle: " + pluginHandle); + } + return rows.front(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginRow"); + } +} +} + +PluginDAOReadOnly::PluginDAOReadOnly(DbPluginHandle pluginHandle) : + m_pluginHandle(pluginHandle) +{ + if (!isPluginInstalled(m_pluginHandle)) { + LogError("Plugin " << m_pluginHandle << " not installed."); + Throw(PluginDAOReadOnly::Exception::PluginNotExist); + } + + checkInstallationCompleted(); +} + +PluginDAOReadOnly::PluginDAOReadOnly(const std::string &libraryName) +{ + LogDebug("PluginDAOReadOnly ( " << libraryName << " )"); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where(Equals( + DPL::FromUTF8String(libraryName))); + + PluginProperties::Select::RowList rows = select->GetRowList(); + if (!rows.empty()) { + m_pluginHandle = rows.front().Get_PluginPropertiesId(); + } else { + ThrowMsg(PluginDAOReadOnly::Exception::PluginNotExist, + "Cannot find plugin: [" + libraryName + "]"); + } + LogDebug(" >> Handle for this plugin: " << m_pluginHandle); + + checkInstallationCompleted(); + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed to connect to database"); + } +} + +void PluginDAOReadOnly::checkInstallationCompleted() +{ + if (getInstallationStateForHandle(m_pluginHandle) + != PluginDAOReadOnly::INSTALLATION_COMPLETED) + { + LogError("Plugin " << m_pluginHandle << " installation not completed"); + Throw(PluginDAOReadOnly::Exception::PluginInstallationNotCompleted); + } +} + +bool PluginDAOReadOnly::isPluginInstalled(const std::string &libraryName) +{ + LogDebug("Check if Library is installed. LibraryName: " << libraryName); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where(Equals( + DPL::FromUTF8String(libraryName))); + + PluginProperties::Select::RowList rows = select->GetRowList(); + + bool flag = !rows.empty(); + LogDebug(" >> Plugin " << libraryName << + (flag ? " found." : " not found.")); + + return flag; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in isPluginInstalled"); + } +} + +PluginHandleList PluginDAOReadOnly::getPluginHandleList() +{ + LogDebug("Getting plugin handle list."); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + + PluginHandleList ret = + select->GetValueList(); + + std::ostringstream handles; + FOREACH(it, ret) + handles << *it << " "; + LogDebug(" >> PluginHandle list retrieved: (" << handles << ")"); + + return ret; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginHandleList"); + } +} + +PluginHandleList PluginDAOReadOnly::getRootPluginHandleList() +{ + LogDebug("Getting root plugin handle list."); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + PluginHandleList handleList = select->GetValueList(); + + WRT_DB_SELECT(select_2nd, PluginDependencies, &WrtDatabase::interface()) + PluginDependencies::Select::RowList dependenciesRows = select_2nd->GetRowList(); + + if (!dependenciesRows.empty()) + { + FOREACH(it, dependenciesRows) + { + handleList.remove(it->Get_PluginPropertiesId()); + } + } + + return handleList; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in getRootPluginHandleList"); + } +} + +DbPluginHandle PluginDAOReadOnly::getPluginHandle() const +{ + return m_pluginHandle; +} + +//"value" cannot be null, as in registerPlugin it is always set +#define RETURN_STD_STRING(in, what) \ + std::string ret = ""; \ + if (!in.IsNull()) { \ + ret = DPL::ToUTF8String(*in); } \ + LogDebug(" >> Plugin " << what << ": " << ret); \ + return ret; + +std::string PluginDAOReadOnly::getLibraryPath() const +{ + LogDebug("Getting plugin library path. Handle: " << m_pluginHandle); + PluginRow row = getPluginRow(m_pluginHandle); + RETURN_STD_STRING(row.Get_PluginLibraryPath(), "library path") +} + +std::string PluginDAOReadOnly::getLibraryName() const +{ + LogDebug("Getting plugin library name. Handle: " << m_pluginHandle); + PluginRow row = getPluginRow(m_pluginHandle); + std::string ret = DPL::ToUTF8String(row.Get_PluginLibraryName()); + LogDebug(" >> Plugin library name: " << ret); + return ret; +} + +#undef RETURN_STD_STRING + +PluginHandleSetPtr PluginDAOReadOnly::getLibraryDependencies() const +{ + Try + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + PluginHandleSetPtr dependencies(new PluginHandleSet); + + WRT_DB_SELECT(select, PluginDependencies, &WrtDatabase::interface()) + select->Where( + Equals(m_pluginHandle)); + + PluginDependencies::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + FOREACH(it, rows) + { + dependencies->insert(it->Get_RequiredPluginPropertiesId()); + } + } + + return dependencies; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetLibraryDependencies"); + } +} + +DbPluginHandle PluginDAOReadOnly::getPluginHandleForImplementedObject( + const std::string& objectName) +{ + LogDebug("GetPluginHandle for object: " << objectName); + + Try + { + DbPluginHandle pluginHandle = INVALID_PLUGIN_HANDLE; + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_SELECT(select, PluginImplementedObjects, &WrtDatabase::interface()) + select->Where( + Equals( + DPL::FromUTF8String(objectName))); + + PluginImplementedObjects::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + pluginHandle = rows.front().Get_PluginPropertiesId(); + } else { + LogWarning("PluginHandle for object not found"); + } + return pluginHandle; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginHandleForImplementedObject"); + } +} + +ImplementedObjectsList PluginDAOReadOnly::getImplementedObjects() +{ + LogDebug("getImplementedObjects"); + + Try + { + ImplementedObjectsList objectList; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_SELECT(select, PluginImplementedObjects, &WrtDatabase::interface()) + std::list valueList = select->GetValueList(); + + if (!valueList.empty()) { + FOREACH(it, valueList) + { + objectList.push_back(DPL::ToUTF8String(*it)); + } + } else { + LogWarning("PluginHandle for object not found"); + } + return objectList; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginHandleForImplementedObject"); + } +} + +ImplementedObjectsList PluginDAOReadOnly::getImplementedObjectsForPluginHandle( + DbPluginHandle handle) +{ + LogDebug("getImplementedObjects for pluginHandle: " << handle); + + Try + { + ImplementedObjectsList objectList; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_SELECT(select, PluginImplementedObjects, &WrtDatabase::interface()) + select->Where( + Equals(handle)); + + PluginImplementedObjects::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + FOREACH(it, rows) + { + objectList.push_back(DPL::ToUTF8String(it->Get_PluginObject())); + } + } else { + LogWarning("PluginHandle for object not found"); + } + return objectList; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginHandleForImplementedObject"); + } +} + +PluginObjectsDAO::ObjectsPtr PluginDAOReadOnly:: + getRequiredObjectsForPluginHandle( + DbPluginHandle handle) +{ + Try + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + PluginObjectsDAO::ObjectsPtr objects = + PluginObjectsDAO::ObjectsPtr(new PluginObjectsDAO::Objects); + + WRT_DB_SELECT(select, PluginRequiredObjects, &WrtDatabase::interface()) + select->Where( + Equals(handle)); + + PluginRequiredObjects::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + FOREACH(it, rows) + { + objects->insert(DPL::ToUTF8String(it->Get_PluginObject())); + } + } + + return objects; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetRequiredObjectsForPluginHandle"); + } +} + +PluginHandleSetPtr PluginDAOReadOnly::getPluginHandleByStatus( + PluginInstallationState state) +{ + Try + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + PluginHandleSetPtr handleSet(new PluginHandleSet); + + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where( + Equals(ToInt(state))); + + PluginProperties::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + FOREACH(it, rows) + { + handleSet->insert(it->Get_PluginPropertiesId()); + } + } + + return handleSet; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetPluginHandleByStatus"); + } +} + +PluginDAOReadOnly::PluginInstallationState PluginDAOReadOnly:: + getInstallationStatus() const +{ + PluginRow row = getPluginRow(m_pluginHandle); + return ToState(row.Get_InstallationState()); +} + +PluginDAOReadOnly::PluginInstallationState PluginDAOReadOnly:: + getInstallationStateForHandle( + DbPluginHandle handle) +{ + Try + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where( + Equals(handle)); + + PluginProperties::Select::RowList rows = select->GetRowList(); + + if (!rows.empty()) { + return ToState(rows.front().Get_InstallationState()); + } + LogError("Data in DB are invalid. Missing field"); + return UNKNOWN_ERROR; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in GetStatusForHandle"); + } +} + +bool PluginDAOReadOnly::isPluginInstalled(DbPluginHandle pluginHandle) +{ + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, PluginProperties, &WrtDatabase::interface()) + select->Where( + Equals(pluginHandle)); + + PluginProperties::Select::RowList rows = select->GetRowList(); + + bool flag = !rows.empty(); + + return flag; + } + Catch(DPL::DB::SqlConnection::Exception::Base) { + ReThrowMsg(PluginDAOReadOnly::Exception::DatabaseError, + "Failed in isPluginInstalled"); + } +} +} // namespace WrtDB diff --git a/modules/widget_dao/dao/property_dao.cpp b/modules/widget_dao/dao/property_dao.cpp new file mode 100644 index 0000000..fa6412a --- /dev/null +++ b/modules/widget_dao/dao/property_dao.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file property_dao.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the definition of property dao class. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +namespace PropertyDAO { +void RemoveProperty(TizenAppId tzAppid, + const PropertyDAOReadOnly::WidgetPropertyKey &key) +{ + //TODO below there are two queries. + // First query asks if given property can be removed, + // Second removes it. Maybe it should be combined two one. + + LogDebug("Removing Property. appid: " << tzAppid << ", key: " << key); + Try { + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + + DPL::OptionalInt readonly = PropertyDAOReadOnly::CheckPropertyReadFlag( + tzAppid, + key); + if (!readonly.IsNull() && *readonly == 1) { + LogError("'" << key << + "' key is readonly. Cannot remove property !"); + ThrowMsg(PropertyDAOReadOnly::Exception::ReadOnlyProperty, + "Property is readonly"); + } + + // Key is not readonly, or has no flag defined + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_DELETE(del, WidgetPreference, &WrtDatabase::interface()) + del->Where(And( + Equals(tzAppid), + Equals(key))); + del->Execute(); + + transaction.Commit(); + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(PropertyDAOReadOnly::Exception::DatabaseError, + "Failure during removing property"); + } +} + +//deprecated +void SetProperty(DbWidgetHandle widgetHandle, + const PropertyDAOReadOnly::WidgetPropertyKey &key, + const PropertyDAOReadOnly::WidgetPropertyValue &value, + bool readOnly) +{ + SetProperty(WidgetDAOReadOnly::getTizenAppId( + widgetHandle), key, value, readOnly); +} + +void SetProperty(TizenAppId tzAppid, + const PropertyDAOReadOnly::WidgetPropertyKey &key, + const PropertyDAOReadOnly::WidgetPropertyValue &value, + bool readOnly) +{ + LogDebug("Setting/updating Property. appid: " << tzAppid << + ", key: " << key); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + + DPL::OptionalInt readonly = PropertyDAOReadOnly::CheckPropertyReadFlag( + tzAppid, + key); + if (!readonly.IsNull() && *readonly == 1) { + LogError("'" << key << + "' key is readonly. Cannot remove property !"); + ThrowMsg(PropertyDAOReadOnly::Exception::ReadOnlyProperty, + "Property is readonly"); + } + DbWidgetHandle widgetHandle(WidgetDAOReadOnly::getHandle(tzAppid)); + + if (readonly.IsNull()) { + WidgetPreference::Row row; + row.Set_app_id(widgetHandle); + row.Set_tizen_appid(tzAppid); + row.Set_key_name(key); + row.Set_key_value(value); + row.Set_readonly(readOnly ? 1 : 0); + + WRT_DB_INSERT(insert, WidgetPreference, &WrtDatabase::interface()) + insert->Values(row); + insert->Execute(); + } else { + WidgetPreference::Row row; + row.Set_key_value(value); + + WRT_DB_UPDATE(update, WidgetPreference, &WrtDatabase::interface()) + update->Where(And( + Equals(tzAppid), + Equals(key))); + + update->Values(row); + update->Execute(); + } + transaction.Commit(); + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(PropertyDAOReadOnly::Exception::DatabaseError, + "Failure during setting/updating property"); + } +} + +void RegisterProperties(DbWidgetHandle widgetHandle, TizenAppId tzAppid, + const WidgetRegisterInfo ®Info) +{ + LogDebug("Registering proferences for widget. appid: " << tzAppid); + + // Try-Catch in WidgetDAO + + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + const ConfigParserData& widgetConfigurationInfo = regInfo.configInfo; + + FOREACH(it, widgetConfigurationInfo.preferencesList) + { + { // Insert into table Widget Preferences + WidgetPreference::Row row; + row.Set_app_id(widgetHandle); + row.Set_tizen_appid(tzAppid); + row.Set_key_name(it->name); + row.Set_key_value(it->value); + int readonly = true == it->readonly ? 1 : 0; + row.Set_readonly(readonly); + + WRT_DB_INSERT(insert, WidgetPreference, &WrtDatabase::interface()) + insert->Values(row); + insert->Execute(); + } + } +} +} // namespace PropertyDAO +} // namespace WrtDB diff --git a/modules/widget_dao/dao/property_dao_read_only.cpp b/modules/widget_dao/dao/property_dao_read_only.cpp new file mode 100644 index 0000000..4916ebc --- /dev/null +++ b/modules/widget_dao/dao/property_dao_read_only.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * property_dao_read_only.cpp + * + * Created on: Nov 16, 2011 + * Author: Krzysztof Jackiewicz(k.jackiewicz@samsung.com) + */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +namespace PropertyDAOReadOnly { +namespace { +typedef DPL::DB::ORM::wrt::WidgetPreference::key_name::ColumnType +ORMWidgetPropertyKey; +typedef DPL::DB::ORM::wrt::WidgetPreference::key_value::ColumnType +ORMWidgetPropertyValue; +typedef std::list +ORMWidgetPreferenceList; +typedef std::list ORMWidgetPropertyKeyList; + +void convertPropertyKey(const ORMWidgetPropertyKey& ormKey, + WidgetPropertyKey& key) +{ + key = ormKey; +} + +void convertPropertyValue(const ORMWidgetPropertyValue& ormPropertyVal, + WidgetPropertyValue& propertyVal) +{ + propertyVal = ormPropertyVal; +} + +void convertWidgetPreferenceRow(const ORMWidgetPreferenceList& ormWidgetPrefRow, + WidgetPreferenceList& prefRow) +{ + FOREACH(it, ormWidgetPrefRow) { + WidgetPreferenceRow row; + + row.appId = it->Get_app_id(); + row.tizen_appid = it->Get_tizen_appid(); + row.key_name = it->Get_key_name(); + row.key_value = it->Get_key_value(); + row.readonly = it->Get_readonly(); + + prefRow.push_back(row); + } +} + +void convertWidgetPropertyKeyList(const ORMWidgetPropertyKeyList& propKeyList, + WidgetPropertyKeyList& keyList) +{ + FOREACH(it, propKeyList) { + keyList.push_back(*it); + } +} + +WidgetPreferenceList GetPropertyListRows(DbWidgetHandle widgetHandle) +{ + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, WidgetPreference, &WrtDatabase::interface()) + select->Where(Equals(widgetHandle)); + ORMWidgetPreferenceList ormPrefList = select->GetRowList(); + WidgetPreferenceList prefList; + convertWidgetPreferenceRow(ormPrefList, prefList); + return prefList; + }Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(Exception::DatabaseError, + "Failure during getting property list"); + } +} +} + +//deprecated +DPL::OptionalInt CheckPropertyReadFlag(DbWidgetHandle widgetHandle, + const WidgetPropertyKey &key) +{ + return CheckPropertyReadFlag(WidgetDAOReadOnly::getTizenAppId(widgetHandle), + key); +} + +DPL::OptionalInt CheckPropertyReadFlag(TizenAppId tzAppid, + const WidgetPropertyKey &key) +{ + LogDebug("Checking Property flag. appid: " << tzAppid << + ", key: " << key); + + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + DbWidgetHandle widgetHandle(WidgetDAOReadOnly::getHandle(tzAppid)); + + WRT_DB_SELECT(select, WidgetPreference, &WrtDatabase::interface()) + select->Where(And(Equals(widgetHandle), + Equals(key))); + + return select->GetSingleValue(); + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(Exception::DatabaseError, + "Failure during checking readonly flag for property"); + } +} + +WidgetPropertyKeyList GetPropertyKeyList(TizenAppId tzAppid) +{ + LogDebug("Get PropertyKey list. appid: " << tzAppid); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + DbWidgetHandle widgetHandle(WidgetDAOReadOnly::getHandle(tzAppid)); + + ORMWidgetPropertyKeyList keyList; + WRT_DB_SELECT(select, WidgetPreference, &WrtDatabase::interface()) + select->Where(Equals(widgetHandle)); + keyList = select->GetValueList(); + + WidgetPropertyKeyList retKeyList; + + convertWidgetPropertyKeyList(keyList, retKeyList); + return retKeyList; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(Exception::DatabaseError, + "Failure during getting propertykey list"); + } +} + +WidgetPreferenceList GetPropertyList(DbWidgetHandle widgetHandle) +{ + if(!(WidgetDAOReadOnly::isWidgetInstalled(widgetHandle))) + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Failed to get widget"); + return GetPropertyListRows(widgetHandle); +} + +WidgetPreferenceList GetPropertyList(TizenAppId tzAppId) +{ + LogDebug("Get Property list. tizenAppId: " << tzAppId); + DbWidgetHandle widgetHandle(WidgetDAOReadOnly::getHandle(tzAppId)); + return GetPropertyListRows(widgetHandle); +} + + +WidgetPropertyValue GetPropertyValue(TizenAppId tzAppid, + const WidgetPropertyKey &key) +{ + LogDebug("Get Property value. appid: " << tzAppid << + ", key: " << key); + Try { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + DbWidgetHandle widgetHandle(WidgetDAOReadOnly::getHandle(tzAppid)); + + WRT_DB_SELECT(select, WidgetPreference, &WrtDatabase::interface()) + select->Where(And(Equals(widgetHandle), + Equals(key))); + + ORMWidgetPropertyValue ormPropValue = + select->GetSingleValue(); + + WidgetPropertyValue propValue; + + convertPropertyValue(ormPropValue, propValue); + + return propValue; + } + Catch(DPL::DB::SqlConnection::Exception::Base){ + ReThrowMsg(Exception::DatabaseError, + "Failure during getting property"); + } +} +} // namespace PropertyDAOReadOnly +} // namespace WrtDB diff --git a/modules/widget_dao/dao/webruntime_database.cpp b/modules/widget_dao/dao/webruntime_database.cpp new file mode 100644 index 0000000..5fbb7d7 --- /dev/null +++ b/modules/widget_dao/dao/webruntime_database.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file webruntime_database.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file contains the definition of webruntime database + */ +#include +#include + +DPL::Mutex g_wrtDbQueriesMutex; + diff --git a/modules/widget_dao/dao/widget_dao.cpp b/modules/widget_dao/dao/widget_dao.cpp new file mode 100755 index 0000000..cc4f79e --- /dev/null +++ b/modules/widget_dao/dao/widget_dao.cpp @@ -0,0 +1,803 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the definition of widget dao class. + * + * @file widget_dao.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Bartosz Janiak (b.janiak@samsung.com) + * @author Yang Jie (jie2.yang@samsung.com) + * @author Koeun Choi(koeun.choi@samsung.com) + * @author Pawel Sikorski(p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the definition of Configuration. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +//TODO in current solution in each getter there exists a check +//"IsWidgetInstalled". Maybe it should be verified, if it could be done +//differently (check in WidgetDAO constructor) + +#define SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN Try + +#define SQL_CONNECTION_EXCEPTION_HANDLER_END(message) \ + Catch(DPL::DB::SqlConnection::Exception::Base) { \ + LogError(message); \ + ReThrowMsg(WidgetDAO::Exception::DatabaseError, \ + message); \ + } + +WidgetDAO::WidgetDAO(DPL::OptionalString widgetGUID) : + WidgetDAOReadOnly(WidgetDAOReadOnly::getHandle(widgetGUID)) +{} + +WidgetDAO::WidgetDAO(DPL::String tzAppId) : + WidgetDAOReadOnly(WidgetDAOReadOnly::getHandle(tzAppId)) +{} + +WidgetDAO::~WidgetDAO() +{} + +void WidgetDAO::setTizenAppId(const DPL::OptionalString& tzAppId) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + using namespace DPL::DB::ORM; + wrt::ScopedTransaction transaction(&WrtDatabase::interface()); + + if (!isWidgetInstalled(getHandle())) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Cannot find widget. Handle: " << getHandle()); + } + + wrt::WidgetInfo::Row row; + row.Set_tizen_appid(*tzAppId); + + WRT_DB_UPDATE(update, wrt::WidgetInfo, &WrtDatabase::interface()) + update->Where( + Equals(getHandle())); + + update->Values(row); + update->Execute(); + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to register widget") +} + +void WidgetDAO::registerWidget( + const TizenAppId & tzAppId, + const WidgetRegisterInfo &widgetRegInfo, + const IWidgetSecurity &widgetSecurity) +{ + LogDebug("Registering widget"); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + registerWidgetInternal(tzAppId, widgetRegInfo, widgetSecurity); + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to register widget") +} + +void WidgetDAO::registerService( + const ConfigParserData::ServiceAppInfo &serviceAppInfo, + const WidgetRegisterInfo &widgetRegInfo, + const IWidgetSecurity &widgetSecurity) +{ + LogDebug("Registering service"); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + + registerServiceInternal(serviceAppInfo, widgetRegInfo, widgetSecurity); + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to register service") +} + + +TizenAppId WidgetDAO::registerWidgetGeneratePkgId( + const WidgetRegisterInfo &pWidgetRegisterInfo, + const IWidgetSecurity &widgetSecurity) +{ + TizenAppId tzAppId = generatePkgId(); + registerWidget(tzAppId, pWidgetRegisterInfo, widgetSecurity); + return tzAppId; +} + +void WidgetDAO::updateTizenAppId( + const TizenAppId & fromAppId, + const TizenAppId & toAppId) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + ScopedTransaction transaction(&WrtDatabase::interface()); + if (!isWidgetInstalled(fromAppId)) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Cannot find widget. tzAppId: " << fromAppId); + } + + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(fromAppId)); + + WidgetInfo::Row row = select->GetSingleRow(); + + //WidgetInfo::Row row; + row.Set_tizen_appid(toAppId); + + WRT_DB_UPDATE(update, WidgetInfo, &WrtDatabase::interface()) + update->Where(Equals(fromAppId)); + update->Values(row); + update->Execute(); + + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to update appid") +} + +void WidgetDAO::registerWidgetInternal( + const TizenAppId & tzAppId, + const WidgetRegisterInfo &widgetRegInfo, + const IWidgetSecurity &widgetSecurity, + const DPL::Optional handle) +{ + //Register into WidgetInfo has to be first + //as all other tables depend upon that + DbWidgetHandle widgetHandle = registerWidgetInfo(tzAppId, widgetRegInfo.tzPkgid, widgetRegInfo.baseFolder, + widgetRegInfo.webAppType.appType, widgetRegInfo.packagingType.pkgType, + widgetRegInfo.configInfo, widgetSecurity,handle); + + registerWidgetExtendedInfo(widgetHandle, widgetRegInfo.installedTime, + widgetRegInfo.configInfo.splashImgSrc, widgetRegInfo.configInfo.backgroundPage, + widgetRegInfo.widgetInstalledPath); + + registerWidgetLocalizedInfo(widgetHandle, widgetRegInfo.configInfo.localizedDataSet); + + registerWidgetIcons(widgetHandle, widgetRegInfo.localizationData.icons); + + registerWidgetStartFile(widgetHandle, widgetRegInfo.localizationData.startFiles); + + PropertyDAO::RegisterProperties(widgetHandle, tzAppId, widgetRegInfo); + + registerWidgetFeatures(widgetHandle, widgetRegInfo.configInfo.featuresList); + + registerWidgetPrivilege(widgetHandle, widgetRegInfo.configInfo.privilegeList); + + registerWidgetWindowModes(widgetHandle, widgetRegInfo.configInfo.windowModes); + + registerWidgetWarpInfo(widgetHandle, widgetRegInfo.configInfo.accessInfoSet); + + registerWidgetAllowNavigationInfo(widgetHandle, widgetRegInfo.configInfo.allowNavigationInfoList); + + registerWidgetCertificates(widgetHandle, widgetSecurity); + + CertificateChainList list; + widgetSecurity.getCertificateChainList(list, SIGNATURE_DISTRIBUTOR); + registerCertificatesChains(widgetHandle, SIGNATURE_DISTRIBUTOR, list); + + list.clear(); + widgetSecurity.getCertificateChainList(list, SIGNATURE_DISTRIBUTOR2); + registerCertificatesChains(widgetHandle, SIGNATURE_DISTRIBUTOR2, list); + + list.clear(); + widgetSecurity.getCertificateChainList(list, SIGNATURE_AUTHOR); + registerCertificatesChains(widgetHandle, SIGNATURE_AUTHOR, list); + + registerWidgetSettings(widgetHandle, widgetRegInfo.configInfo.settingsList); + + registerAppControl(widgetHandle, widgetRegInfo.configInfo.appControlList); + + registerEncryptedResouceInfo(widgetHandle, widgetRegInfo.encryptedFiles); + + registerExternalLocations(widgetHandle, widgetRegInfo.externalLocations); +} + +#define DO_INSERT(row, table) \ + { \ + WRT_DB_INSERT(insert, table, &WrtDatabase::interface()) \ + insert->Values(row); \ + insert->Execute(); \ + } + +void WidgetDAO::registerWidgetExtendedInfo(DbWidgetHandle widgetHandle, + time_t installedTime, + const DPL::OptionalString & splashImgSrc, const DPL::OptionalString & backgroundPage, + const DPL::OptionalString & widgetInstalledPath) +{ + //Try and transaction not needed + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + WidgetExtendedInfo::Row row; + row.Set_app_id(widgetHandle); + row.Set_install_time(installedTime); + row.Set_splash_img_src(splashImgSrc); + row.Set_background_page(backgroundPage); + row.Set_installed_path(widgetInstalledPath); + + DO_INSERT(row, WidgetExtendedInfo) +} + +DbWidgetHandle WidgetDAO::registerWidgetInfo( + const TizenAppId & tzAppId, + const TizenPkgId & tzPkgId, + const std::string & baseFolder, + AppType appType, + PkgType pkgType, + const ConfigParserData &widgetConfigurationInfo, + const IWidgetSecurity &widgetSecurity, + const DPL::Optional handle) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + // TODO in wrt_db all Columns in WidgetInfo have DEFAULT VALUE set. + // Because of that, "Optional" is not used there + + WidgetInfo::Row row; + if (!!handle) { + row.Set_app_id(*handle); + } + + row.Set_widget_type(appType); + row.Set_widget_id(widgetConfigurationInfo.widget_id); + row.Set_defaultlocale(widgetConfigurationInfo.defaultlocale); + row.Set_widget_version(widgetConfigurationInfo.version); + row.Set_widget_width(widgetConfigurationInfo.width); + row.Set_widget_height(widgetConfigurationInfo.height); + row.Set_author_name(widgetConfigurationInfo.authorName); + row.Set_author_email(widgetConfigurationInfo.authorEmail); + row.Set_author_href(widgetConfigurationInfo.authorHref); + row.Set_csp_policy(widgetConfigurationInfo.cspPolicy); + row.Set_csp_policy_report_only(widgetConfigurationInfo.cspPolicyReportOnly); + row.Set_base_folder(DPL::FromUTF8String(baseFolder)); + row.Set_webkit_plugins_required(widgetConfigurationInfo.flashNeeded); + row.Set_tizen_appid(tzAppId); + row.Set_tizen_pkgid(tzPkgId); + { + if (!!widgetConfigurationInfo.minVersionRequired) { + row.Set_min_version(widgetConfigurationInfo.minVersionRequired); + } else if (!!widgetConfigurationInfo.tizenMinVersionRequired) { + row.Set_min_version(widgetConfigurationInfo.tizenMinVersionRequired); + } + } + row.Set_back_supported(widgetConfigurationInfo.backSupported); + row.Set_access_network(widgetConfigurationInfo.accessNetwork); + row.Set_pkg_type(pkgType); + row.Set_security_model_version( + static_cast(widgetConfigurationInfo.securityModelVersion)); + + Try + { + DO_INSERT(row, WidgetInfo); + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + ReThrowMsg(WidgetDAO::Exception::DatabaseError, + "Failed to register widget info."); + } + + if (!handle) { + //get autoincremented value of widgetHandle + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(tzAppId)); + return select->GetSingleValue(); + } else { + return *handle; + } +} + +void WidgetDAO::registerWidgetLocalizedInfo(DbWidgetHandle widgetHandle, + const ConfigParserData::LocalizedDataSet &localizedDataSet) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + FOREACH(it, localizedDataSet) + { + const DPL::String& locale = it->first; + const ConfigParserData::LocalizedData& data = it->second; + + LocalizedWidgetInfo::Row row; + row.Set_app_id(widgetHandle); + row.Set_widget_locale(locale); + row.Set_widget_name(data.name); + row.Set_widget_shortname(data.shortName); + row.Set_widget_description(data.description); + row.Set_widget_license(data.license); + row.Set_widget_license_file(data.licenseFile); + row.Set_widget_license_href(data.licenseHref); + + DO_INSERT(row, LocalizedWidgetInfo) + } +} + +void WidgetDAO::registerWidgetIcons(DbWidgetHandle widgetHandle, + const WidgetRegisterInfo::LocalizedIconList &icons) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + FOREACH(i, icons) + { + wrt::WidgetIcon::icon_id::ColumnType icon_id; + { + wrt::WidgetIcon::Row row; + row.Set_app_id(widgetHandle); + row.Set_icon_src(i->src); + row.Set_icon_width(i->width); + row.Set_icon_height(i->height); + + WRT_DB_INSERT(insert, wrt::WidgetIcon, &WrtDatabase::interface()) + insert->Values(row); + icon_id = static_cast(insert->Execute()); + } + + FOREACH(j, i->availableLocales) + { + WidgetLocalizedIcon::Row row; + row.Set_app_id(widgetHandle); + row.Set_icon_id(icon_id); + row.Set_widget_locale(*j); + DO_INSERT(row, WidgetLocalizedIcon) + } + } +} + +void WidgetDAO::registerWidgetStartFile(DbWidgetHandle widgetHandle, + const WidgetRegisterInfo::LocalizedStartFileList &startFiles) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + FOREACH(i, startFiles) + { + WidgetStartFile::start_file_id::ColumnType startFileID; + { + WidgetStartFile::Row row; + row.Set_app_id(widgetHandle); + row.Set_src(i->path); + + WRT_DB_INSERT(insert, WidgetStartFile, &WrtDatabase::interface()) + insert->Values(row); + startFileID = static_cast(insert->Execute()); + } + + FOREACH(j, i->propertiesForLocales) + { + WidgetLocalizedStartFile::Row row; + row.Set_app_id(widgetHandle); + row.Set_start_file_id(startFileID); + row.Set_widget_locale(j->first); + row.Set_type(j->second.type); + row.Set_encoding(j->second.encoding); + + DO_INSERT(row, WidgetLocalizedStartFile) + } + } +} + +void WidgetDAO::registerWidgetFeatures(DbWidgetHandle widgetHandle, + const ConfigParserData::FeaturesList &featuresList) +{ + using namespace DPL::DB::ORM; + FOREACH(pWidgetFeature, featuresList) + { + wrt::WidgetFeature::Row widgetFeature; + widgetFeature.Set_app_id(widgetHandle); + widgetFeature.Set_name(pWidgetFeature->name); + widgetFeature.Set_rejected(false); + + DO_INSERT(widgetFeature, wrt::WidgetFeature) + } +} + +void WidgetDAO::registerWidgetPrivilege(DbWidgetHandle widgetHandle, + const ConfigParserData::PrivilegeList &privilegeList) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + FOREACH(it, privilegeList) + { + WidgetPrivilege::Row widgetPrivilege; + widgetPrivilege.Set_app_id(widgetHandle); + widgetPrivilege.Set_name(it->name); + + DO_INSERT(widgetPrivilege, WidgetPrivilege) + } +} + +void WidgetDAO::updateFeatureRejectStatus(const DbWidgetFeature &widgetFeature) +{ + // This function could be merged with registerWidgetFeature but it requires + // desing change: + // 1. Check "ace step" in installer must be done before "update database + // step" + // And: + // ConfigurationParserData shouldn't be called "ParserData" any more. + using namespace DPL::DB::ORM; + + wrt::ScopedTransaction transaction(&WrtDatabase::interface()); + WRT_DB_SELECT(select, wrt::WidgetFeature, &WrtDatabase::interface()) + select->Where(And(Equals(m_widgetHandle), + Equals(widgetFeature.name))); + + auto row = select->GetSingleRow(); + row.Set_rejected(widgetFeature.rejected); + + WRT_DB_UPDATE(update, wrt::WidgetFeature, &WrtDatabase::interface()) + update->Where(And(Equals(m_widgetHandle), + Equals(widgetFeature.name))); + update->Values(row); + update->Execute(); + transaction.Commit(); +} + +void WidgetDAO::registerWidgetWindowModes(DbWidgetHandle widgetHandle, + const ConfigParserData::StringsList &windowModes) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + FOREACH(i, windowModes) + { + wrt::WidgetWindowModes::Row windowMode; + windowMode.Set_app_id(widgetHandle); + windowMode.Set_window_mode(*i); + + DO_INSERT(windowMode, wrt::WidgetWindowModes) + } +} + +void WidgetDAO::registerWidgetWarpInfo(DbWidgetHandle widgetHandle, + const ConfigParserData::AccessInfoSet &accessInfoSet) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + FOREACH(AccIt, accessInfoSet) + { + WidgetWARPInfo::Row row; + row.Set_app_id(widgetHandle); + row.Set_iri(AccIt->m_strIRI); + row.Set_subdomain_access(static_cast ( + AccIt->m_bSubDomainAccess)); + + DO_INSERT(row, WidgetWARPInfo) + } +} + +void WidgetDAO::registerWidgetAllowNavigationInfo(DbWidgetHandle widgetHandle, + const ConfigParserData::AllowNavigationInfoList &allowNavigationInfoList) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + FOREACH(allowNaviIt, allowNavigationInfoList) + { + WidgetAllowNavigation::Row row; + row.Set_app_id(widgetHandle); + row.Set_scheme(allowNaviIt->m_scheme); + row.Set_host(allowNaviIt->m_host); + DO_INSERT(row, WidgetAllowNavigation) + } +} + +void WidgetDAO::registerWidgetCertificates(DbWidgetHandle widgetHandle, + const IWidgetSecurity &widgetSecurity) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + FOREACH(it, widgetSecurity.getCertificateList()) + { + WidgetCertificateFingerprint::Row row; + row.Set_app_id(widgetHandle); + row.Set_owner(it->owner); + row.Set_chainid(it->chainId); + row.Set_type(it->type); + row.Set_md5_fingerprint(DPL::FromUTF8String(it->strMD5Fingerprint)); + row.Set_sha1_fingerprint(DPL::FromUTF8String(it->strSHA1Fingerprint)); + row.Set_common_name(it->strCommonName); + + DO_INSERT(row, WidgetCertificateFingerprint) + } +} + +void WidgetDAO::registerCertificatesChains( + DbWidgetHandle widgetHandle, + CertificateSource certificateSource, + const CertificateChainList & + certificateChainList) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + FOREACH(certChain, certificateChainList) + { + WidgetCertificate::Row row; + row.Set_app_id(widgetHandle); + row.Set_cert_source(certificateSource); + row.Set_encoded_chain(DPL::FromASCIIString(*certChain)); + + DO_INSERT(row, WidgetCertificate); + } +} + +void WidgetDAO::registerWidgetSettings(DbWidgetHandle widgetHandle, + const ConfigParserData::SettingsList &settingsList) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + FOREACH(pWidgetSetting, settingsList) + { + SettingsList::Row row; + row.Set_appId(widgetHandle); + row.Set_settingName(pWidgetSetting->m_name); + row.Set_settingValue(pWidgetSetting->m_value); + + DO_INSERT(row, SettingsList) + } +} + +void WidgetDAO::insertAppControlInfo(DbWidgetHandle handle, + DPL::String src, + DPL::String operation, + DPL::String uri, + DPL::String mime, + unsigned index, + unsigned disposition) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + AppControlInfo::Row row; + + row.Set_app_id(handle); + row.Set_execute_index(index); + row.Set_src(src); + row.Set_operation(operation); + row.Set_uri(uri); + row.Set_mime(mime); + row.Set_disposition(disposition); + + DO_INSERT(row, AppControlInfo); +} + +void WidgetDAO::registerAppControl(DbWidgetHandle widgetHandle, + const ConfigParserData::AppControlInfoList &appControlList) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + // appControlList + FOREACH(appControl_it, appControlList) + { + DPL::String src = appControl_it->m_src; + DPL::String operation = appControl_it->m_operation; + unsigned index = appControl_it->m_index; + unsigned disposition = + static_cast(appControl_it->m_disposition); + + if (!appControl_it->m_uriList.empty()) + { + FOREACH(uri_it, appControl_it->m_uriList) + { + DPL::String uri = *uri_it; + + if (!appControl_it->m_mimeList.empty()) + { + FOREACH(mime_it, appControl_it->m_mimeList) + { + DPL::String mime = *mime_it; + + insertAppControlInfo(widgetHandle, src, operation, uri, mime, index, disposition); + } + } + else + { + DPL::String mime = L""; + + insertAppControlInfo(widgetHandle, src, operation, uri, mime, index, disposition); + } + } + } + else + { + DPL::String uri = L""; + + if (!appControl_it->m_mimeList.empty()) + { + FOREACH(mime_it, appControl_it->m_mimeList) + { + DPL::String mime = *mime_it; + + insertAppControlInfo(widgetHandle, src, operation, uri, mime, index, disposition); + } + } + else + { + DPL::String mime = L""; + + insertAppControlInfo(widgetHandle, src, operation, uri, mime, index, disposition); + } + } + } +} + +void WidgetDAO::registerEncryptedResouceInfo(DbWidgetHandle widgetHandle, + const EncryptedFileList &encryptedFiles) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + FOREACH(it, encryptedFiles) + { + EncryptedResourceList::Row row; + row.Set_app_id(widgetHandle); + row.Set_resource(it->fileName); + row.Set_size(it->fileSize); + + DO_INSERT(row, EncryptedResourceList) + } +} + +void WidgetDAO::registerServiceInternal(const ConfigParserData::ServiceAppInfo &serviceAppInfo, const WidgetRegisterInfo &widgetRegInfo, const IWidgetSecurity &widgetSecurity) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + DPL::String tzAppId = serviceAppInfo.serviceId; + + + DbWidgetHandle widgetHandle = registerWidgetInfo(tzAppId, widgetRegInfo.tzPkgid, widgetRegInfo.baseFolder, + APP_TYPE_TIZENWEBSERVICE, widgetRegInfo.packagingType.pkgType, + widgetRegInfo.configInfo, widgetSecurity); + + registerWidgetExtendedInfo(widgetHandle, widgetRegInfo.installedTime, + widgetRegInfo.configInfo.splashImgSrc, widgetRegInfo.configInfo.backgroundPage, + widgetRegInfo.widgetInstalledPath); + + registerWidgetLocalizedInfo(widgetHandle, serviceAppInfo.m_localizedDataSet); + + + WidgetRegisterInfo::LocalizedIconList iconList; + LocaleSet localeSet; + FOREACH(it, serviceAppInfo.m_iconsList) { + iconList.push_back(WidgetRegisterInfo::LocalizedIcon(*it, localeSet)); + } + registerWidgetIcons(widgetHandle, iconList); + + WidgetRegisterInfo::LocalizedStartFileList startFileList; + WidgetRegisterInfo::LocalizedStartFile startFile; + WidgetRegisterInfo::StartFileProperties startFileProperties; + startFile.path = serviceAppInfo.serviceContent; + startFileProperties.type = L""; + startFileProperties.encoding = L"UTF-8"; + startFile.propertiesForLocales[L""] = startFileProperties; + startFileList.push_back(startFile); + registerWidgetStartFile(widgetHandle, startFileList); + + + PropertyDAO::RegisterProperties(widgetHandle, tzAppId, widgetRegInfo); + + registerWidgetFeatures(widgetHandle, widgetRegInfo.configInfo.featuresList); + + registerWidgetPrivilege(widgetHandle, widgetRegInfo.configInfo.privilegeList); + + registerWidgetWindowModes(widgetHandle, widgetRegInfo.configInfo.windowModes); + + registerWidgetWarpInfo(widgetHandle, widgetRegInfo.configInfo.accessInfoSet); + + registerWidgetAllowNavigationInfo(widgetHandle, widgetRegInfo.configInfo.allowNavigationInfoList); + + registerWidgetCertificates(widgetHandle, widgetSecurity); + + CertificateChainList list; + widgetSecurity.getCertificateChainList(list, SIGNATURE_DISTRIBUTOR); + registerCertificatesChains(widgetHandle, SIGNATURE_DISTRIBUTOR, list); + + list.clear(); + widgetSecurity.getCertificateChainList(list, SIGNATURE_AUTHOR); + registerCertificatesChains(widgetHandle, SIGNATURE_AUTHOR, list); + + registerWidgetSettings(widgetHandle, widgetRegInfo.configInfo.settingsList); + + registerEncryptedResouceInfo(widgetHandle, widgetRegInfo.encryptedFiles); + + registerExternalLocations(widgetHandle, widgetRegInfo.externalLocations); +} + +void WidgetDAO::registerExternalLocations( + DbWidgetHandle widgetHandle, + const ExternalLocationList & + externals) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + LogDebug("Inserting external files for widgetHandle: " << widgetHandle); + FOREACH(it, externals) + { + WidgetExternalLocations::Row row; + row.Set_app_id(widgetHandle); + row.Set_path(DPL::FromUTF8String(*it)); + + DO_INSERT(row, WidgetExternalLocations) + } + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to register external files"); +} + +void WidgetDAO::unregisterAllExternalLocations() +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + LogDebug("Deleting external files for widgetHandle: " << m_widgetHandle); + WRT_DB_DELETE(del, WidgetExternalLocations, &WrtDatabase::interface()); + del->Where(Equals(m_widgetHandle)); + del->Execute(); +} + +void WidgetDAO::unregisterWidget(const TizenAppId & tzAppId) +{ + LogDebug("Unregistering widget from DB. tzAppId: " << tzAppId); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + DPL::DB::ORM::wrt::ScopedTransaction transaction( + &WrtDatabase::interface()); + unregisterWidgetInternal(tzAppId); + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to unregister widget") +} + +void WidgetDAO::unregisterWidgetInternal( + const TizenAppId & tzAppId) +{ + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + + DbWidgetHandle handle = getHandle(tzAppId); + + // Delete from table Widget Info + WRT_DB_DELETE(del, WidgetInfo, &WrtDatabase::interface()) + del->Where(Equals(handle)); + del->Execute(); + + // Deleting in other tables is done via "delete cascade" in SQL +} + +#undef DO_INSERT + +#undef SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN +#undef SQL_CONNECTION_EXCEPTION_HANDLER_END +} // namespace WrtDB diff --git a/modules/widget_dao/dao/widget_dao_read_only.cpp b/modules/widget_dao/dao/widget_dao_read_only.cpp new file mode 100755 index 0000000..01e2f6c --- /dev/null +++ b/modules/widget_dao/dao/widget_dao_read_only.cpp @@ -0,0 +1,1192 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of widget dao class. + * + * @file widget_dao_read_only.cpp + * @author Yang Jie (jie2.yang@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of widget dao + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + unsigned int seed = time(NULL); +} + +namespace WrtDB { +//TODO in current solution in each getter there exists a check +//"IsWidgetInstalled". Maybe it should be verified, if it could be done +//differently (check in WidgetDAOReadOnly constructor) + +#define SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN Try + +#define SQL_CONNECTION_EXCEPTION_HANDLER_END(message) \ + Catch(DPL::DB::SqlConnection::Exception::Base) { \ + LogError(message); \ + ReThrowMsg(WidgetDAOReadOnly::Exception::DatabaseError, \ + message); \ + } + +#define CHECK_WIDGET_EXISTENCE(macro_transaction, macro_handle) \ + if (!WidgetDAOReadOnly::isWidgetInstalled(macro_handle)) \ + { \ + macro_transaction.Commit(); \ + LogWarning("Cannot find widget. Handle: " << macro_handle); \ + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, \ + "Cannot find widget. Handle: " << macro_handle); \ + } + +typedef DPL::DB::ORM::wrt::WidgetInfo::Row WidgetInfoRow; +typedef DPL::DB::ORM::wrt::WidgetFeature::widget_feature_id::ColumnType +WidgetFeatureId; + +namespace { +using namespace DPL::DB::ORM; +using namespace DPL::DB::ORM::wrt; + +WidgetInfoRow getWidgetInfoRow(int widgetHandle) +{ + LogDebug("Getting WidgetInfo row. Handle: " << widgetHandle); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(widgetHandle)); + + WidgetInfo::Select::RowList rows = select->GetRowList(); + if (rows.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Cannot find widget. Handle: " << widgetHandle); + } + return rows.front(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed in GetWidgetInfoRow") +} + +const int MAX_TIZENID_LENGTH = 10; + +TizenAppId getTizenAppIdByHandle(const DbWidgetHandle handle) +{ + LogDebug("Getting TizenAppId by DbWidgetHandle: " << handle); + + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(handle)); + WidgetInfo::Select::RowList rowList = select->GetRowList(); + + if (rowList.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Failed to get widget by handle"); + } + TizenAppId tzAppid = rowList.front().Get_tizen_appid(); + + return tzAppid; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed in getHandle") +} + +TizenAppId getTizenAppIdByPkgId(const TizenPkgId tzPkgid) +{ + LogDebug("Getting TizenAppId by pkgid : " << tzPkgid); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(tzPkgid)); + WidgetInfo::Select::RowList rowList = select->GetRowList(); + + if (rowList.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Failed to get widget by handle"); + } + TizenAppId tzAppid = rowList.front().Get_tizen_appid(); + + return tzAppid; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed in getHandle") +} + +void getTizenAppIdListByPkgId(const TizenPkgId tzPkgid, std::list& idList) +{ + LogDebug("Getting TizenAppId by pkgid : " << tzPkgid); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(tzPkgid)); + WidgetInfo::Select::RowList rowList = select->GetRowList(); + + for (WidgetInfo::Select::RowList::iterator i = rowList.begin(); i != rowList.end(); ++i) { + TizenAppId tzAppid = i->Get_tizen_appid(); + idList.push_back(tzAppid); + } + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed in getHandle") +} + +TizenPkgId getTizenPkgIdByHandle(const DbWidgetHandle handle) +{ + LogDebug("Getting TizenPkgId by DbWidgetHandle: " << handle); + + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(handle)); + WidgetInfo::Select::RowList rowList = select->GetRowList(); + + if (rowList.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Failed to get widget by handle"); + } + TizenPkgId tzPkgid = rowList.front().Get_tizen_pkgid(); + + return tzPkgid; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed in getHandle") +} + +TizenPkgId getTizenPkgIdByAppId(const TizenAppId tzAppid) +{ + LogDebug("Getting TizenPkgId by TizenAppId: " << tzAppid); + + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(tzAppid)); + WidgetInfo::Select::RowList rowList = select->GetRowList(); + + if (rowList.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Failed to get widget by tizen appId"); + } + TizenPkgId tzPkgid = rowList.front().Get_tizen_pkgid(); + + return tzPkgid; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed get pkgId") +} +} // namespace + +IWidgetSecurity::~IWidgetSecurity() +{} + +WidgetDAOReadOnly::WidgetDAOReadOnly(DbWidgetHandle widgetHandle) : + m_widgetHandle(widgetHandle) +{} + +WidgetDAOReadOnly::WidgetDAOReadOnly(DPL::OptionalString widgetGUID) : + m_widgetHandle(WidgetDAOReadOnly::getHandle(widgetGUID)) +{} + +WidgetDAOReadOnly::WidgetDAOReadOnly(TizenAppId tzAppid) : + m_widgetHandle(WidgetDAOReadOnly::getHandle(tzAppid)) +{} + +WidgetDAOReadOnly::~WidgetDAOReadOnly() +{} + +DbWidgetHandle WidgetDAOReadOnly::getHandle() const +{ + return m_widgetHandle; +} + +DbWidgetHandle WidgetDAOReadOnly::getHandle(const WidgetGUID GUID) +{ + LogDebug("Getting WidgetHandle by GUID [" << GUID << "]"); + + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(GUID)); + WidgetInfo::Select::RowList rowList = select->GetRowList(); + + if (rowList.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Failed to get widget by guid"); + } + return rowList.front().Get_app_id(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed in getHandle") +} + +DbWidgetHandle WidgetDAOReadOnly::getHandle(const DPL::String tzAppId) +{ + LogDebug("Getting WidgetHandle by tizen app id [" << tzAppId << "]"); + + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(tzAppId)); + WidgetInfo::Select::RowList rowList = select->GetRowList(); + + if (rowList.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Failed to get widget by package name"); + } + return rowList.front().Get_app_id(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed in getHandle") +} + +DbWidgetHandle WidgetDAOReadOnly::getHandleByPkgId(const DPL::String pkgId) +{ + LogDebug("Getting WidgetHandle by tizen package id [" << pkgId << "]"); + + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(pkgId)); + WidgetInfo::Select::RowList rowList = select->GetRowList(); + + if (rowList.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Failed to get widget by package id"); + } + return rowList.front().Get_app_id(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed in getHandle") +} + + +TizenAppId WidgetDAOReadOnly::getTzAppId() const +{ + return getTizenAppIdByHandle(m_widgetHandle); +} + +TizenAppId WidgetDAOReadOnly::getTzAppId(const WidgetGUID GUID) +{ + return getTizenAppIdByHandle(getHandle(GUID)); +} + +TizenAppId WidgetDAOReadOnly::getTzAppId(const DbWidgetHandle handle) +{ + return getTizenAppIdByHandle(handle); +} + +TizenAppId WidgetDAOReadOnly::getTzAppId(const TizenPkgId tzPkgid) +{ + return getTizenAppIdByPkgId(tzPkgid); +} + +TizenAppId WidgetDAOReadOnly::getTizenAppId() const +{ + return getTizenAppIdByHandle(m_widgetHandle); +} + +TizenAppId WidgetDAOReadOnly::getTizenAppId(const WidgetGUID GUID) +{ + return getTizenAppIdByHandle(getHandle(GUID)); +} + +TizenAppId WidgetDAOReadOnly::getTizenAppId(const DbWidgetHandle handle) +{ + return getTizenAppIdByHandle(handle); +} + +TizenAppId WidgetDAOReadOnly::getTizenAppId(const TizenPkgId tzPkgid) +{ + return getTizenAppIdByPkgId(tzPkgid); +} + +TizenAppIdList WidgetDAOReadOnly::getTizenAppidList() +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + return select->GetValueList(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get TizenAppIdList") +} + +TizenAppIdList WidgetDAOReadOnly::getTizenAppIdList() +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + return select->GetValueList(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get TizenAppIdList") +} + +std::list WidgetDAOReadOnly::getTzAppIdList(const TizenPkgId tzPkgid){ + std::list result; + getTizenAppIdListByPkgId(tzPkgid, result); + return result; +} + +TizenPkgId WidgetDAOReadOnly::getTzPkgId() const +{ + return getTizenPkgIdByHandle(m_widgetHandle); +} + +TizenPkgId WidgetDAOReadOnly::getTzPkgId(const DbWidgetHandle handle) +{ + return getTizenPkgIdByHandle(handle); +} + +TizenPkgId WidgetDAOReadOnly::getTzPkgId(const TizenAppId tzAppid) +{ + return getTizenPkgIdByAppId(tzAppid); +} + +TizenPkgId WidgetDAOReadOnly::getTizenPkgId() const +{ + return getTizenPkgIdByHandle(m_widgetHandle); +} + +TizenPkgId WidgetDAOReadOnly::getTizenPkgId(const DbWidgetHandle handle) +{ + return getTizenPkgIdByHandle(handle); +} + +TizenPkgId WidgetDAOReadOnly::getTizenPkgId(const TizenAppId tzAppid) +{ + return getTizenPkgIdByAppId(tzAppid); +} + +TizenPkgIdList WidgetDAOReadOnly::getTizenPkgidList() +{ + LogDebug("Getting Pkgid List "); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + return select->GetValueList(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get Pkgid list") +} + +TizenPkgIdList WidgetDAOReadOnly::getTizenPkgIdList() +{ + LogDebug("Getting TizenPkgId List "); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + return select->GetValueList(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get Pkgid list") +} + +PropertyDAOReadOnly::WidgetPropertyKeyList +WidgetDAOReadOnly::getPropertyKeyList() const +{ + return PropertyDAOReadOnly::GetPropertyKeyList(getTizenAppId()); +} + +PropertyDAOReadOnly::WidgetPreferenceList +WidgetDAOReadOnly::getPropertyList() const +{ + return PropertyDAOReadOnly::GetPropertyList(getTizenAppId()); +} + +PropertyDAOReadOnly::WidgetPropertyValue WidgetDAOReadOnly::getPropertyValue( + const PropertyDAOReadOnly::WidgetPropertyKey &key) const +{ + return PropertyDAOReadOnly::GetPropertyValue(getTizenAppId(), key); +} + +DPL::OptionalInt WidgetDAOReadOnly::checkPropertyReadFlag( + const PropertyDAOReadOnly::WidgetPropertyKey &key) const +{ + return PropertyDAOReadOnly::CheckPropertyReadFlag(getTizenAppId(), key); +} + +DPL::String WidgetDAOReadOnly::getPath() const +{ + DPL::String path = *getWidgetInstalledPath(); + DPL::String srcPath = DPL::FromUTF8String(GlobalConfig::GetWidgetSrcPath()); + + path += srcPath + L"/"; + + return path; +} + +DPL::String WidgetDAOReadOnly::getFullPath() const +{ + return L"file://" + getPath(); +} + +WidgetLocalizedInfo +WidgetDAOReadOnly::getLocalizedInfo(const DPL::String& languageTag) +const +{ + LogDebug("Getting Localized Info. Handle: " << m_widgetHandle); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + ScopedTransaction transaction(&WrtDatabase::interface()); + CHECK_WIDGET_EXISTENCE(transaction, m_widgetHandle) + + WRT_DB_SELECT(select, LocalizedWidgetInfo, &WrtDatabase::interface()) + select->Where( + And(Equals(m_widgetHandle), + Equals(languageTag))); + LocalizedWidgetInfo::Row info = select->GetSingleRow(); + WidgetLocalizedInfo result; + + result.name = info.Get_widget_name(); + result.shortName = info.Get_widget_shortname(); + result.description = info.Get_widget_description(); + result.license = info.Get_widget_license(); + result.licenseHref = info.Get_widget_license_href(); + + transaction.Commit(); + return result; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get localized info") +} + +DbWidgetFeatureSet WidgetDAOReadOnly::getFeaturesList() const +{ + LogDebug("Getting FeaturesList. Handle: " << m_widgetHandle); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + ScopedTransaction transaction(&WrtDatabase::interface()); + CHECK_WIDGET_EXISTENCE(transaction, m_widgetHandle) + + WRT_DB_SELECT(select, WidgetFeature, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + DbWidgetFeatureSet resultSet; + typedef std::list RowList; + RowList list = select->GetRowList(); + + for (RowList::iterator i = list.begin(); i != list.end(); ++i) { + DbWidgetFeature feature; + feature.name = i->Get_name(); + feature.rejected = i->Get_rejected(); + FeatureDAOReadOnly featureDao(DPL::ToUTF8String(i->Get_name())); + feature.pluginId = featureDao.GetPluginHandle(); + resultSet.insert(feature); + } + transaction.Commit(); + return resultSet; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get features list") +} + +bool WidgetDAOReadOnly::hasFeature(const std::string& featureName) const +{ + LogDebug( + "Checking if widget has feature: " << featureName << ". Handle: " << + m_widgetHandle); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + ScopedTransaction transaction(&WrtDatabase::interface()); + CHECK_WIDGET_EXISTENCE(transaction, m_widgetHandle) + + WRT_DB_SELECT(select, wrt::WidgetFeature, &WrtDatabase::interface()) + select->Where(And(Equals(m_widgetHandle), + Equals( + DPL::FromUTF8String(featureName)))); + + wrt::WidgetFeature::Select::RowList rows = select->GetRowList(); + transaction.Commit(); + return !rows.empty(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to check for feature") +} + +DbWidgetDAOReadOnlyList WidgetDAOReadOnly::getWidgetList() +{ + LogDebug("Getting DbWidget List"); + DbWidgetDAOReadOnlyList list; + FOREACH(iterator, getTizenAppidList()) { + list.push_back(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(*iterator))); + } + return list; +} + +bool WidgetDAOReadOnly::isWidgetInstalled(DbWidgetHandle handle) +{ + LogDebug("Checking if widget exist. Handle: " << handle); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(handle)); + + WidgetInfo::Select::RowList rows = select->GetRowList(); + + return !rows.empty(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to check if widget exist") +} + +bool WidgetDAOReadOnly::isWidgetInstalled(const TizenAppId &tzAppId) +{ + LogDebug("Checking if widget exist. tizen app id" << tzAppId); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(tzAppId)); + + WidgetInfo::Select::RowList rows = select->GetRowList(); + + return !rows.empty(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to check if widget exist") +} + +ExternalLocationList WidgetDAOReadOnly::getWidgetExternalLocations() const +{ + LogDebug("Getting WidgetExtranalFiles List"); + ExternalLocationList result; + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetExternalLocations, &WrtDatabase::interface()); + select->Where(Equals(m_widgetHandle)); + WidgetExternalLocations::Select::RowList rows = select->GetRowList(); + FOREACH(it, rows) + { + result.push_back(DPL::ToUTF8String(it->Get_path())); + } + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get handle list") + return result; +} + +CertificateChainList WidgetDAOReadOnly::getWidgetCertificate( + CertificateSource source) const +{ + WRT_DB_SELECT(select, WidgetCertificate, &WrtDatabase::interface()) + select->Where( + And( + Equals(m_widgetHandle), + Equals(source))); + + std::list chainList = select->GetRowList(); + + CertificateChainList result; + + FOREACH(iter, chainList) + result.push_back(DPL::ToUTF8String(iter->Get_encoded_chain())); + return result; +} + +DbWidgetSize WidgetDAOReadOnly::getPreferredSize() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + + DbWidgetSize size; + size.width = row.Get_widget_width(); + size.height = row.Get_widget_height(); + + LogDebug("Return size wxh = " << + (!!size.width ? *size.width : -1) << " x " << + (!!size.height ? *size.height : -1)); + + return size; +} + +WidgetType WidgetDAOReadOnly::getWidgetType() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + DPL::OptionalInt result = row.Get_widget_type(); + return WidgetType(static_cast(*result)); +} + +WidgetGUID WidgetDAOReadOnly::getGUID() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_widget_id(); +} + +DPL::OptionalString WidgetDAOReadOnly::getDefaultlocale() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_defaultlocale(); +} + +DPL::Optional WidgetDAOReadOnly::getVersion() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_widget_version(); +} + +DPL::Optional WidgetDAOReadOnly::getAuthorName() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_author_name(); +} + +DPL::Optional WidgetDAOReadOnly::getAuthorEmail() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_author_email(); +} + +DPL::Optional WidgetDAOReadOnly::getAuthorHref() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_author_href(); +} + +DPL::Optional WidgetDAOReadOnly::getMinimumWacVersion() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_min_version(); +} + +bool WidgetDAOReadOnly::getBackSupported() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_back_supported(); +} + +DPL::OptionalString WidgetDAOReadOnly::getCspPolicy() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_csp_policy(); +} + +DPL::OptionalString WidgetDAOReadOnly::getCspPolicyReportOnly() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + return row.Get_csp_policy_report_only(); +} + +bool WidgetDAOReadOnly::getWebkitPluginsRequired() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + DPL::OptionalInt ret = row.Get_webkit_plugins_required(); + + if (ret.IsNull() || *ret == 0) { + return false; + } else { return true; + } +} + +time_t WidgetDAOReadOnly::getInstallTime() const +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetExtendedInfo, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + WidgetExtendedInfo::Select::RowList rows = select->GetRowList(); + if (rows.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Cannot find widget. Handle: " << m_widgetHandle); + } + + return static_cast(*rows.front().Get_install_time()); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get widdget install time") +} + +DPL::OptionalString WidgetDAOReadOnly::getSplashImgSrc() const +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetExtendedInfo, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + WidgetExtendedInfo::Select::RowList rows = select->GetRowList(); + if (rows.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Cannot find widget. Handle: " << m_widgetHandle); + } + + DPL::OptionalString value = rows.front().Get_splash_img_src(); + if (value.IsNull()) { + return DPL::OptionalString::Null; + } + + return DPL::OptionalString(getPath() + *value); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get splash image path") +} + +WidgetDAOReadOnly::WidgetLocalizedIconList WidgetDAOReadOnly:: + getLocalizedIconList() const +{ + //TODO check widget existance?? + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetLocalizedIcon, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + std::list list = + select->GetRowList(); + WidgetLocalizedIconList ret; + FOREACH(it, list) + { + WidgetLocalizedIconRow icon = { it->Get_app_id(), + it->Get_icon_id(), + it->Get_widget_locale() }; + ret.push_back(icon); + } + return ret; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get icon data") +} + +WidgetDAOReadOnly::WidgetIconList WidgetDAOReadOnly::getIconList() const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, wrt::WidgetIcon, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + select->OrderBy(DPL::TypeListDecl >()); + + std::list list = + select->GetRowList(); + WidgetIconList ret; + FOREACH(it, list) + { + WidgetIconRow icon = { it->Get_icon_id(), + it->Get_app_id(), + it->Get_icon_src(), + it->Get_icon_width(), + it->Get_icon_height() }; + ret.push_back(icon); + } + return ret; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get icon data") +} + +WidgetDAOReadOnly::LocalizedStartFileList WidgetDAOReadOnly:: + getLocalizedStartFileList() const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetLocalizedStartFile, &WrtDatabase::interface()) + select->Where(Equals( + m_widgetHandle)); + select->OrderBy("start_file_id ASC"); + + std::list list = + select->GetRowList(); + LocalizedStartFileList ret; + FOREACH(it, list) + { + WidgetLocalizedStartFileRow file = { it->Get_start_file_id(), + it->Get_app_id(), + it->Get_widget_locale(), + it->Get_type(), + it->Get_encoding() }; + ret.push_back(file); + } + return ret; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get start file list data") +} + +WidgetDAOReadOnly::WidgetStartFileList WidgetDAOReadOnly::getStartFileList() +const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetStartFile, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + select->OrderBy("start_file_id ASC"); + + std::list list = + select->GetRowList(); + WidgetStartFileList ret; + FOREACH(it, list) + { + WidgetStartFileRow file = { it->Get_start_file_id(), + it->Get_app_id(), + it->Get_src() }; + ret.push_back(file); + } + return ret; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get start file list data") +} + +WindowModeList WidgetDAOReadOnly::getWindowModes() const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetWindowModes, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + return select->GetValueList(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get window modes") +} + +std::string WidgetDAOReadOnly::getBaseFolder() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + DPL::Optional ret = row.Get_base_folder(); + std::string baseFolder; + if (!ret.IsNull()) { + baseFolder = DPL::ToUTF8String(*ret); + } + + if (!baseFolder.empty()) { + baseFolder += "/"; + } + + return baseFolder; +} + +WidgetCertificateDataList WidgetDAOReadOnly::getCertificateDataList() const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, + WidgetCertificateFingerprint, + &WrtDatabase::interface()) + select->Where(Equals( + m_widgetHandle)); + select->OrderBy("chainid"); + WidgetCertificateFingerprint::Select::RowList rows = + select->GetRowList(); + + WidgetCertificateDataList outlCertificateData; + FOREACH(it, rows) + { + WidgetCertificateData data; + + data.owner = + static_cast (it->Get_owner()); + data.type = + static_cast (it->Get_type()); + data.chainId = it->Get_chainid(); + DPL::Optional md5 = it->Get_md5_fingerprint(); + data.strMD5Fingerprint = + md5.IsNull() ? "" : DPL::ToUTF8String(*md5); + DPL::Optional sha1 = it->Get_sha1_fingerprint(); + data.strSHA1Fingerprint = + sha1.IsNull() ? "" : DPL::ToUTF8String(*sha1); + DPL::Optional cname = it->Get_common_name(); + data.strCommonName = + cname.IsNull() ? DPL::FromUTF8String("") : *cname; + + outlCertificateData.push_back(data); + } + return outlCertificateData; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get fingerprint list") +} + +FingerPrintList WidgetDAOReadOnly::getKeyFingerprints( + WidgetCertificateData::Owner owner, + WidgetCertificateData::Type type) const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, + WidgetCertificateFingerprint, + &WrtDatabase::interface()) + select->Where(And(And( + Equals( + m_widgetHandle), + Equals(owner)), + Equals(type))); + + WidgetCertificateFingerprint::Select::RowList rows = + select->GetRowList(); + + FingerPrintList keys; + FOREACH(it, rows) + { + DPL::Optional sha1 = it->Get_sha1_fingerprint(); + if (!sha1.IsNull()) { + keys.push_back(DPL::ToUTF8String(*sha1)); + } + DPL::Optional md5 = it->Get_md5_fingerprint(); + if (!md5.IsNull()) { + keys.push_back(DPL::ToUTF8String(*md5)); + } + } + return keys; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get fingerprint list") +} + +WidgetCertificateCNList WidgetDAOReadOnly::getKeyCommonNameList( + WidgetCertificateData::Owner owner, + WidgetCertificateData::Type type) const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, + WidgetCertificateFingerprint, + &WrtDatabase::interface()) + select->Where(And(And( + Equals( + m_widgetHandle), + Equals(owner)), + Equals(type))); + + WidgetCertificateFingerprint::Select::RowList rows = + select->GetRowList(); + + WidgetCertificateCNList out; + FOREACH(it, rows) + { + DPL::Optional cname = it->Get_common_name(); + out.push_back(cname.IsNull() ? "" : DPL::ToUTF8String(*cname)); + } + return out; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get key common name") +} + +void WidgetDAOReadOnly::getWidgetAccessInfo( + WidgetAccessInfoList& outAccessInfoList) const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetWARPInfo, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + WidgetWARPInfo::Select::RowList rows = select->GetRowList(); + + FOREACH(it, rows) + { + WidgetAccessInfo info; + + info.strIRI = it->Get_iri(); + DPL::OptionalInt access = it->Get_subdomain_access(); + if (access.IsNull() || 0 == *access) { + info.bSubDomains = false; + } else if (1 == *access) { + info.bSubDomains = true; + } + + outAccessInfoList.push_back(info); + } + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get accessinfo list") +} + +void WidgetDAOReadOnly::getWidgetAllowNavigationInfo( + WidgetAllowNavigationInfoList& allowNavigationList) const +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetAllowNavigation, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + WidgetAllowNavigation::Select::RowList rows = select->GetRowList(); + + FOREACH(it, rows) { + WidgetAllowNavigationInfo info; + info.scheme = it->Get_scheme(); + info.host = it->Get_host(); + allowNavigationList.push_back(info); + } + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get allow-navigation info list") +} + +LanguageTags WidgetDAOReadOnly::getLanguageTags() const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, LocalizedWidgetInfo, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + return select->GetValueList(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get language tags") +} + +LanguageTags WidgetDAOReadOnly::getIconLanguageTags() const +{ + //TODO check widget existance + WRT_DB_SELECT(select, WidgetLocalizedIcon, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + select->Distinct(); + return select->GetValueList(); +} + +void WidgetDAOReadOnly::getWidgetSettings( + WidgetSettings& outWidgetSettings) const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, SettingsList, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + SettingsList::Select::RowList rows = select->GetRowList(); + + FOREACH(it, rows) + { + WidgetSetting info; + + info.settingName = it->Get_settingName(); + info.settingValue = it->Get_settingValue(); + outWidgetSettings.push_back(info); + } + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get settings list") +} + +void WidgetDAOReadOnly::getAppControlList( + WidgetAppControlList& outAppControlList) const +{ + LogDebug("Getting getAppControlList. Handle: " << m_widgetHandle); + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + ScopedTransaction transaction(&WrtDatabase::interface()); + CHECK_WIDGET_EXISTENCE(transaction, m_widgetHandle) + + WRT_DB_SELECT(select, AppControlInfo, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + AppControlInfo::Select::RowList rows = select->GetRowList(); + + if (rows.empty()) { + LogDebug("AppControl list is empty. Handle: " << + m_widgetHandle); + } + + FOREACH(it, rows) { + WidgetAppControl ret; + ret.src = it->Get_src(); + ret.operation = it->Get_operation(); + ret.uri = it->Get_uri(); + ret.mime = it->Get_mime(); + ret.disposition = static_cast(it->Get_disposition()); + ret.index = it->Get_execute_index(); + outAppControlList.push_back(ret); + } + + transaction.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get AppControl list") +} + +PackagingType WidgetDAOReadOnly::getPackagingType() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + DPL::OptionalInt result = row.Get_pkg_type(); + return PackagingType(static_cast(*result)); +} + +void WidgetDAOReadOnly::getEncryptedFileList(EncryptedFileList& filesList) +const +{ + //TODO check widget existance + WRT_DB_SELECT(select, EncryptedResourceList, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + typedef std::list RowList; + RowList list = select->GetRowList(); + + FOREACH(it, list) { + EncryptedFileInfo info; + info.fileName = it->Get_resource(); + info.fileSize = it->Get_size(); + filesList.insert(info); + } +} + +DPL::OptionalString WidgetDAOReadOnly::getBackgroundPage() const +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetExtendedInfo, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + WidgetExtendedInfo::Select::RowList rows = select->GetRowList(); + if (rows.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Cannot find widget. Handle: " << m_widgetHandle); + } + + return rows.front().Get_background_page(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get background page") +} + +TizenPkgId WidgetDAOReadOnly::generatePkgId() +{ + std::string allowed("0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"); + TizenPkgId pkgId; + pkgId.resize(MAX_TIZENID_LENGTH); + do { + for (int i = 0; i < MAX_TIZENID_LENGTH; ++i) { + pkgId[i] = allowed[rand_r(&seed) % allowed.length()]; + } + } while (isWidgetInstalled(pkgId)); + return pkgId; +} + +DPL::OptionalString WidgetDAOReadOnly::getWidgetInstalledPath() const +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::wrt; + WRT_DB_SELECT(select, WidgetExtendedInfo, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + WidgetExtendedInfo::Select::RowList rows = select->GetRowList(); + if (rows.empty()) { + ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist, + "Cannot find widget. Handle: " << m_widgetHandle); + } + + return rows.front().Get_installed_path(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get widdget installed path") +} + +PrivilegeList WidgetDAOReadOnly::getWidgetPrivilege() const +{ + //TODO check widget existance + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WRT_DB_SELECT(select, WidgetPrivilege, &WrtDatabase::interface()) + select->Where(Equals(m_widgetHandle)); + + return select->GetValueList(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get PrivilegeList") +} + +WidgetSecurityModelVersion WidgetDAOReadOnly::getSecurityModelVersion() const +{ + WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle); + DPL::OptionalInt result = row.Get_security_model_version(); + return static_cast(*result); +} + +#undef SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN +#undef SQL_CONNECTION_EXCEPTION_HANDLER_END +#undef CHECK_WIDGET_EXISTENCE +} // namespace WrtDB diff --git a/modules/widget_dao/dao/widget_dao_types.cpp b/modules/widget_dao/dao/widget_dao_types.cpp new file mode 100644 index 0000000..1296b28 --- /dev/null +++ b/modules/widget_dao/dao/widget_dao_types.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file widget_dao_types.cpp + * @author Leerang Song (leerang.song@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of + * common data types forwidget database. + */ + +#include +#include + +namespace WrtDB { + +const std::map g_W3CPrivilegeTextMap = { + {"http://tizen.org/privilege/location", FEATURE_GEOLOCATION}, + {"http://tizen.org/privilege/notification", FEATURE_WEB_NOTIFICATION}, + {"http://tizen.org/privilege/mediacapture", FEATURE_USER_MEDIA}, + {"http://tizen.org/privilege/fullscreen", FEATURE_FULLSCREEN_MODE}, + {"http://tizen.org/privilege/unlimitedstorage", FEATURE_WEB_DATABASE}, + {"http://tizen.org/privilege/camera", FEATURE_CAMERA}, + {"http://tizen.org/privilege/audiorecorder", FEATURE_AUDIO_RECORDER} +}; +} // namespace SecurityOriginDB diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/WrtDatabase.h b/modules/widget_dao/include/dpl/wrt-dao-ro/WrtDatabase.h new file mode 100644 index 0000000..8caa49f --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/WrtDatabase.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef WRT_SRC_CONFIGURATION_WRTDATABASE_H_ +#define WRT_SRC_CONFIGURATION_WRTDATABASE_H_ + +#include + +namespace WrtDB { +class WrtDatabase +{ + public: + static const char *Address(); + static DPL::DB::SqlConnection::Flag::Type Flags(); + static void attachToThreadRO(); + static void attachToThreadRW(); + static void detachFromThread(); + static DPL::DB::ThreadDatabaseSupport& interface(); + static bool CheckTableExist(const char *name); + + private: + static DPL::DB::ThreadDatabaseSupport m_interface; +}; +} + +#endif /* WRTDATABASE_H */ + diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/common_dao_types.h b/modules/widget_dao/include/dpl/wrt-dao-ro/common_dao_types.h new file mode 100755 index 0000000..d734efa --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/common_dao_types.h @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file common_dao_types.h + * @author Michal Ciepielski (m.ciepielski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of common data types for wrtdb + */ + +#ifndef WRT_WIDGET_DAO_COMMON_DAO_TYPES_H_ +#define WRT_WIDGET_DAO_COMMON_DAO_TYPES_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +class PluginMetafileData +{ + public: + struct Feature + { + std::string m_name; + std::set m_deviceCapabilities; + + bool operator< (const Feature& obj) const + { + return m_name < obj.m_name; + } + }; + typedef std::set FeatureContainer; + + public: + + PluginMetafileData() + {} + + std::string m_libraryName; + FeatureContainer m_featureContainer; +}; + +class PluginObjectsDAO +{ + public: + typedef std::set Objects; + typedef std::shared_ptr ObjectsPtr; + + public: + explicit PluginObjectsDAO() {} + + protected: + ObjectsPtr m_implemented; + ObjectsPtr m_dependent; +}; + +/** + * @brief Widget id describes web-runtime global widget identifier. + * + * Notice that only up to one widget can exist at the same time. + * DbWidgetHandle can be translated into corresponding WidgetModel by invoking + * FindWidgetModel routine. + */ +typedef int DbWidgetHandle; +typedef DPL::String TizenPkgId; +typedef DPL::String TizenAppId; + +/** + * Value of invalid widget handle + */ +enum { + INVALID_WIDGET_HANDLE = -1 +}; + +/** + * @brief Structure to hold the information of widget's size + */ +struct DbWidgetSize +{ + DPL::OptionalInt width; + DPL::OptionalInt height; + + DbWidgetSize(DPL::OptionalInt w = DPL::OptionalInt::Null, + DPL::OptionalInt h = DPL::OptionalInt::Null) : + width(w), + height(h) + {} +}; + +inline bool operator ==(const DbWidgetSize &objA, const DbWidgetSize &objB) +{ + if (!objA.height || !objA.width || !objB.width || !objB.height) { + return false; + } else { + return *objA.height == *objB.height && *objA.width == *objB.width; + } +} + +/** + * Widget [G]lobal [U]nique [ID]entifier + * Orginated from appstore ID + */ +typedef DPL::OptionalString WidgetGUID; + +struct WidgetAccessInfo +{ + DPL::String strIRI; /* origin iri */ + bool bSubDomains; /* do we want access to subdomains ? */ + + bool operator ==(const WidgetAccessInfo& info) const + { + return info.strIRI == strIRI && + info.bSubDomains == bSubDomains; + } +}; +typedef std::list WidgetAccessInfoList; + +struct WidgetAllowNavigationInfo +{ + DPL::String scheme; + DPL::String host; +}; +typedef std::list WidgetAllowNavigationInfoList; + +struct EncryptedFileInfo +{ + DPL::String fileName; + int fileSize; + + bool operator==(const EncryptedFileInfo& info) const + { + return fileName == info.fileName; + } + + bool operator==(const DPL::String& file) const + { + return fileName == file; + } + + bool operator< (const EncryptedFileInfo& info) const + { + return fileName < info.fileName; + } +}; + +typedef std::list WindowModeList; + +typedef std::list PrivilegeList; + +typedef std::set EncryptedFileList; + +/** + * @brief Widget feature host information about possible javascript extensions + * that widget may use + * + * Widget features are declared in configuration file in widget installation + * package. Each declared special feature is contained in some wrt-plugin that + * declares to implement it. After widget launch wrt searches for proper plugin + * libraries and load needed features. + * + * Widget features can be required or optional. It is possible to start widget + * without missing feature. When required feature cannot be loaded widget will + * not start. + */ + +enum { + INVALID_PLUGIN_HANDLE = -1 +}; +typedef int DbPluginHandle; + +struct DbWidgetFeature +{ + DPL::String name; /// Feature name + bool rejected; /// Api feature was rejected by ace + DbPluginHandle pluginId; /// Plugin id that implement this feature + + DbWidgetFeature() : + pluginId(INVALID_PLUGIN_HANDLE) + {} +}; + +inline bool operator < (const DbWidgetFeature &objA, + const DbWidgetFeature &objB) +{ + return objA.name.compare(objB.name) < 0; +} + +inline bool operator==(const DbWidgetFeature &featureA, + const DbWidgetFeature &featureB) +{ + return featureA.name == featureB.name && + featureA.pluginId == featureB.pluginId; +} + +/** + * @brief Default container for features list + */ +typedef std::multiset DbWidgetFeatureSet; + +/** + * @brief Default container with DbWidgetHandle's + */ +typedef std::list DbWidgetHandleList; +typedef std::list TizenAppIdList; +typedef std::list TizenPkgIdList; + +class WidgetDAOReadOnly; //forward declaration +typedef std::shared_ptr WidgetDAOReadOnlyPtr; +/** + * @brief Default container with WidgetDAOReadOnly + */ +typedef std::list DbWidgetDAOReadOnlyList; + +/** + * @brief Widget specific type + * + * Widget type describes belowed in WAC, TIZEN WebApp + */ +enum AppType +{ + APP_TYPE_UNKNOWN = 0, // unknown + APP_TYPE_TIZENWEBAPP, // Tizen webapp + APP_TYPE_TIZENWEBSERVICE // Tizen web service +}; + +class WidgetType +{ + public: + WidgetType() : + appType(APP_TYPE_UNKNOWN) + {} + WidgetType(const AppType type) : + appType(type) + {} + bool operator== (const AppType& other) const + { + return appType == other; + } + bool operator!= (const AppType& other) const + { + return appType != other; + } + std::string getApptypeToString() + { + switch (appType) { +#define X(x) case x: return #x; + X(APP_TYPE_UNKNOWN) + X(APP_TYPE_TIZENWEBAPP) + X(APP_TYPE_TIZENWEBSERVICE) + +#undef X + default: + return "UNKNOWN"; + } + } + + AppType appType; +}; + +/** + * @brief Package specific type + * + * Package type describes belowed in Tizen webapp, C++ service App + */ +enum PkgType +{ + PKG_TYPE_UNKNOWN = 0, // unknown + PKG_TYPE_NOMAL_WEB_APP, + PKG_TYPE_DIRECTORY_WEB_APP, + PKG_TYPE_HOSTED_WEB_APP, // request from browser + PKG_TYPE_HYBRID_WEB_APP // Tizen webapp with C++ service app +}; + +class PackagingType +{ + public: + PackagingType() : + pkgType(PKG_TYPE_UNKNOWN) + {} + PackagingType(const PkgType type) : + pkgType(type) + {} + bool operator== (const PkgType& other) const + { + return pkgType == other; + } + bool operator!= (const PkgType& other) const + { + return pkgType != other; + } + std::string getPkgtypeToString() + { + switch (pkgType) { +#define X(x) case x: return #x; + X(PKG_TYPE_UNKNOWN) + X(PKG_TYPE_NOMAL_WEB_APP) + X(PKG_TYPE_DIRECTORY_WEB_APP) + X(PKG_TYPE_HOSTED_WEB_APP) + X(PKG_TYPE_HYBRID_WEB_APP) +#undef X + default: + return "UNKNOWN"; + } + } + + PkgType pkgType; +}; + +struct WidgetSetting +{ + DPL::String settingName; + DPL::String settingValue; + + bool operator ==(const WidgetSetting& info) const + { + return (info.settingName == settingName && + info.settingValue == settingValue); + } + bool operator !=(const WidgetSetting& info) const + { + return (info.settingName != settingName || + info.settingValue != settingValue); + } +}; + +typedef std::list WidgetSettings; + +/** + * @brief Widget AppControl + * + * Application control describes details of behaviour + * when widget receives aul bundle data. + */ +namespace AppControlPrefix { + const char* const PROCESS_PREFIX = "-__CONTROL_PROCESS__"; +} +struct WidgetAppControl +{ + enum class Disposition { + UNDEFINE = 0, + WINDOW = 1, + INLINE = 2 + }; + + DPL::String src; /* start uri */ + DPL::String operation; /* service name */ + DPL::String uri; /* scheme type*/ + DPL::String mime; /* mime type */ + Disposition disposition; + unsigned index; + + bool operator== (const WidgetAppControl& other) const + { + return src == other.src && + operation == other.operation && + uri == other.uri && + mime == other.mime && + disposition == other.disposition; + } +}; + +typedef std::list WidgetAppControlList; + +enum class WidgetSecurityModelVersion +{ + WIDGET_SECURITY_MODEL_V1 = 0, // WARP + WIDGET_SECURITY_MODEL_V2 // CSP, allow-navigation +}; +} // namespace WrtDB +#endif /* WRT_WIDGET_DAO_COMMON_DAO_TYPES_H_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/config_parser_data.h b/modules/widget_dao/include/dpl/wrt-dao-ro/config_parser_data.h new file mode 100755 index 0000000..7357c08 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/config_parser_data.h @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file config_parser_data.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#ifndef CONFIG_PARSER_DATA_H_ +#define CONFIG_PARSER_DATA_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +void NormalizeString(DPL::OptionalString& txt, bool isTrimSpace = false); +void NormalizeString(DPL::String& str); +DPL::String GetSingleAttributeValue(const DPL::String value); +void NormalizeAndTrimSpaceString(DPL::OptionalString& txt); + +class WidgetConfigurationManager; + +class ConfigParserData +{ + public: + struct Feature + { + Feature(const DPL::String& _name) : name(_name) + {} + DPL::String name; + + bool operator==(const Feature&) const; + bool operator!=(const Feature&) const; + bool operator >(const Feature&) const; + bool operator>=(const Feature&) const; + bool operator <(const Feature&) const; + bool operator<=(const Feature&) const; + }; + typedef std::set FeaturesList; + + struct Privilege + { + Privilege(const DPL::String& _name) : name(_name) + {} + DPL::String name; + + bool operator==(const Privilege&) const; + bool operator!=(const Privilege&) const; + bool operator >(const Privilege&) const; + bool operator>=(const Privilege&) const; + bool operator <(const Privilege&) const; + bool operator<=(const Privilege&) const; + }; + typedef std::set PrivilegeList; + + struct Icon + { + Icon(const DPL::String& _src) : src(_src), isSmall(false) + {} + DPL::String src; + DPL::OptionalInt width; + DPL::OptionalInt height; + bool isSmall; + bool operator==(const Icon&) const; + bool operator!=(const Icon&) const; + bool operator >(const Icon&) const; + bool operator>=(const Icon&) const; + bool operator <(const Icon&) const; + bool operator<=(const Icon&) const; + }; + typedef std::list IconsList; + + struct LocalizedData + { + DPL::OptionalString name; + DPL::OptionalString shortName; + + DPL::OptionalString description; + + DPL::OptionalString license; + DPL::OptionalString licenseFile; + DPL::OptionalString licenseHref; + }; + typedef std::map LocalizedDataSet; + + struct Preference + { + Preference(const DPL::String& _name, + bool _readonly = false) : + name(_name), + value(), + readonly(_readonly) + {} + DPL::String name; + DPL::OptionalString value; + bool readonly; + bool operator==(const Preference&) const; + bool operator!=(const Preference&) const; + bool operator >(const Preference&) const; + bool operator>=(const Preference&) const; + bool operator <(const Preference&) const; + bool operator<=(const Preference&) const; + }; + typedef std::set PreferencesList; + typedef std::set StringsList; + + struct AccessInfo + { + AccessInfo(const DPL::String& strIRI, + bool bSubdomainAccess) : m_strIRI(strIRI), + m_bSubDomainAccess(bSubdomainAccess) + {} + + bool operator==(const AccessInfo&) const; + bool operator!=(const AccessInfo&) const; + bool operator <(const AccessInfo&) const; + + DPL::String m_strIRI; + bool m_bSubDomainAccess; + }; + typedef std::set AccessInfoSet; + + struct Setting + { + Setting(const DPL::String& name, + const DPL::String& value) : + m_name(name), + m_value(value) + {} + DPL::String m_name; + DPL::String m_value; + + bool operator==(const Setting&) const; + bool operator!=(const Setting&) const; + bool operator >(const Setting&) const; + bool operator>=(const Setting&) const; + bool operator <(const Setting&) const; + bool operator<=(const Setting&) const; + }; + + typedef std::set SettingsList; + + struct AppControlInfo + { + enum class Disposition { + UNDEFINE = 0, + WINDOW = 1, + INLINE = 2 + }; + AppControlInfo(const DPL::String& operation) : + m_operation(operation), + m_disposition(Disposition::UNDEFINE), + m_index(0) + {} + DPL::String m_src; + DPL::String m_operation; + std::set m_uriList; + std::set m_mimeList; + Disposition m_disposition; + unsigned m_index; + + bool operator==(const AppControlInfo&) const; + bool operator!=(const AppControlInfo&) const; + }; + + typedef std::list AppControlInfoList; + + struct LiveboxInfo + { + LiveboxInfo() { } + + struct BoxSize + { + DPL::String m_size; + DPL::String m_preview; + DPL::String m_useDecoration; + }; + typedef BoxSize BoxSizeInfo; + typedef std::list BoxSizeList; + + struct BoxContent + { + DPL::String m_boxSrc; + DPL::String m_boxMouseEvent; + DPL::String m_boxTouchEffect; + BoxSizeList m_boxSize; + DPL::String m_pdSrc; + DPL::String m_pdWidth; + DPL::String m_pdHeight; + DPL::String m_pdFastOpen; + }; + typedef BoxContent BoxContentInfo; + + typedef std::list > BoxLabelList; + + BoxLabelList m_label; + DPL::String m_icon; + DPL::String m_liveboxId; + DPL::String m_primary; + DPL::String m_type; + DPL::String m_autoLaunch; + DPL::String m_updatePeriod; + BoxContentInfo m_boxInfo; + + bool operator==(const LiveboxInfo&) const; + bool operator!=(const LiveboxInfo&) const; + bool operator >(const LiveboxInfo&) const; + bool operator>=(const LiveboxInfo&) const; + bool operator <(const LiveboxInfo&) const; + bool operator<=(const LiveboxInfo&) const; + }; + typedef DPL::Optional OptionalLiveboxInfo; + typedef std::list LiveboxList; + + enum IconSectionType + { + DefaultIcon =0, + SmallIcon + }; + + typedef std::set> IconSet; + typedef std::list CapabilityList; + typedef std::set> DisplayNameSet; + + struct AccountProvider + { + AccountProvider() : + m_multiAccountSupport(false) + { } + + bool m_multiAccountSupport; + IconSet m_iconSet; + DisplayNameSet m_displayNameSet; + CapabilityList m_capabilityList; + }; + + typedef std::list DependsPkgList; + typedef std::set CategoryList; + + struct AllowNavigationInfo + { + AllowNavigationInfo(DPL::String scheme, + DPL::String host) : + m_scheme(scheme), + m_host(host) + { } + DPL::String m_scheme; + DPL::String m_host; + }; + typedef std::list AllowNavigationInfoList; + + struct Metadata + { + Metadata(const DPL::OptionalString& _key, + const DPL::OptionalString& _value) : + key(_key), + value(_value) + {} + DPL::OptionalString key; + DPL::OptionalString value; + + bool operator==(const Metadata&) const; + bool operator!=(const Metadata&) const; + }; + typedef std::list MetadataList; + + struct ImeAppInfo + { + DPL::String uuid; + typedef std::set LanguageList; + LanguageList languageList; + }; + typedef std::list ImeAppInfoList; + + struct ServiceAppInfo + { + ServiceAppInfo() : onBoot(false), autoRestart(false) { } + + DPL::String serviceId; + bool onBoot; + bool autoRestart; + LocalizedDataSet m_localizedDataSet; + DPL::String serviceContent; + IconsList m_iconsList; + MetadataList m_metadataList; + CategoryList m_categoryList; + }; + typedef std::list ServiceAppInfoList; + + enum class SecurityModelVersion { + SECURITY_MODEL_V1 = 0, // WARP + SECURITY_MODEL_V2 // CSP, allow-navigation + }; + + LiveboxList m_livebox; + StringsList nameSpaces; + + LocalizedDataSet localizedDataSet; + + DPL::OptionalString authorName; + DPL::OptionalString authorHref; + DPL::OptionalString authorEmail; + + FeaturesList featuresList; + PrivilegeList privilegeList; + + SettingsList settingsList; + + DPL::OptionalInt width; + DPL::OptionalInt height; + + DPL::OptionalString widget_id; + DPL::OptionalString defaultlocale; + + PreferencesList preferencesList; + + DPL::OptionalString version; + StringsList windowModes; + + AccessInfoSet accessInfoSet; + + bool flashNeeded; + + DPL::OptionalString minVersionRequired; + + bool backSupported; + bool accessNetwork; + + // Unlocalized data, to be processed by WidgetConfigurationManager + bool startFileEncountered; + DPL::OptionalString startFile; + DPL::OptionalString startFileEncoding; + DPL::OptionalString startFileContentType; + DPL::OptionalString startFileNamespace; + IconsList iconsList; + + // tizen id / required platform min version for TIZEN webapp + DPL::OptionalString tizenMinVersionRequired; + DPL::OptionalString tizenPkgId; + DPL::OptionalString tizenAppId; + bool didFoundTizenApplicationElement; + + // allow-navigation + bool allowNavigationEncountered; + AllowNavigationInfoList allowNavigationInfoList; + + //csp polic for widget + bool cspPolicyEncountered; + DPL::OptionalString cspPolicy; + bool cspPolicyReportOnlyEncountered; + DPL::OptionalString cspPolicyReportOnly; + + //AppControl model list + AppControlInfoList appControlList; + + // For link shared directory + DependsPkgList dependsPkgList; + // Splash image path + DPL::OptionalString splashImgSrc; + // Background page filename + DPL::OptionalString backgroundPage; + // For category + CategoryList categoryList; + // For Account + AccountProvider accountProvider; + // security model version + SecurityModelVersion securityModelVersion; + // security model version + MetadataList metadataList; + //ime app + ImeAppInfoList imeAppInfoList; + //service app + ServiceAppInfoList serviceAppInfoList; + + ConfigParserData() : + flashNeeded(false), + minVersionRequired(), + backSupported(false), + accessNetwork(false), + startFileEncountered(false), + didFoundTizenApplicationElement(false), + allowNavigationEncountered(false), + cspPolicyEncountered(false), + cspPolicyReportOnlyEncountered(false), + securityModelVersion(SecurityModelVersion::SECURITY_MODEL_V1) + {} +}; +} // namespace WrtDB + +#endif //CONFIG_PARSER_DATA_H_ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/feature_dao_read_only.h b/modules/widget_dao/include/dpl/wrt-dao-ro/feature_dao_read_only.h new file mode 100644 index 0000000..f366012 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/feature_dao_read_only.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file feature_dao_read_only.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of feature dao read only + */ + +#ifndef WRT_SRC_CONFIGURATION_FEATURE_DAO_READ_ONLY_H_ +#define WRT_SRC_CONFIGURATION_FEATURE_DAO_READ_ONLY_H_ + +#include +#include +#include +#include +#include "feature_model.h" +#include +#include + +namespace WrtDB { +// TODO: Move to feature_model.h +typedef std::set DeviceCapabilitySet; + +class FeatureDAOReadOnly +{ + public: + /** + * Exception classes + */ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DatabaseError) + DECLARE_EXCEPTION_TYPE(Base, FeatureNotExist) + }; + + // TODO: Move to feature_model.h + typedef std::set DeviceCapabilitiesList; + typedef std::multimap DeviceCapabilitiesMap; + typedef std::map NameMap; + typedef std::map FeatureMap; + + static bool isDeviceCapabilityInstalled(const std::string &deviceCapName); + + FeatureDAOReadOnly(FeatureHandle); + FeatureDAOReadOnly(const std::string &featureName); + + static FeatureHandleListPtr GetFeatureHandleListForPlugin( + DbPluginHandle pluginHandle); + + static bool isFeatureInstalled(const std::string &featureName); + static bool isFeatureInstalled(FeatureHandle handle); + static FeatureHandleList GetHandleList(); + + std::string GetName() const; + FeatureHandle GetFeatureHandle() const; + std::string GetLibraryPath() const; + std::string GetLibraryName() const; + DeviceCapabilitiesList GetDeviceCapabilities() const; + DbPluginHandle GetPluginHandle() const; + + static NameMap GetNames(); + static DeviceCapabilitiesMap GetDevCapWithFeatureHandle(); + static DeviceCapabilitySet GetDeviceCapability(const DPL::String &apifeature); + + static FeatureMap GetFeatures(const std::list& featureNames); + + protected: + FeatureHandle m_featureHandle; +}; +} // namespace WrtDB + +#endif /* WRT_SRC_CONFIGURATION_FEATURE_DAO_READ_ONLY_H_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/feature_model.h b/modules/widget_dao/include/dpl/wrt-dao-ro/feature_model.h new file mode 100644 index 0000000..8698d4a --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/feature_model.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file feature_model.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief This file contains FeatureModel, FeatureHandle definitions. + */ +#ifndef FEATURE_MODEL_H +#define FEATURE_MODEL_H + +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +typedef int FeatureHandle; +typedef std::list FeatureHandleList; +typedef std::shared_ptr FeatureHandleListPtr; + +typedef int FeatureSetHandle; +typedef std::list FeatureSetHandleList; + +typedef struct { + std::string featureName; + DbPluginHandle pluginHandle; +} FeatureData; + +class FeatureModel : public DPL::Event::Model +{ + public: + DPL::Event::Property FHandle; + DPL::Event::Property Name; + + DPL::Event::Property > DeviceCapabilities; + DPL::Event::Property PHandle; + + FeatureModel(FeatureHandle handle) : + FHandle(this, handle), + Name(this), + DeviceCapabilities(this), + PHandle(this, -1) + {} + + void SetData(const std::string& name, + const std::set& deviceCapabilities, + const DbPluginHandle& pluginHandle) + { + Name.SetWithoutLock(name); + DeviceCapabilities.SetWithoutLock(deviceCapabilities); + PHandle.SetWithoutLock(pluginHandle); + } +}; + +typedef std::shared_ptr FeatureModelPtr; +} // namespace WrtDB + +#endif // FEATURE_MODEL_H diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/global_config.h b/modules/widget_dao/include/dpl/wrt-dao-ro/global_config.h new file mode 100644 index 0000000..2b055c4 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/global_config.h @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file global_config.h + * @author Yang Jie (jie2.yang@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file contains global WRT config + */ +#ifndef GLOBAL_CONFIG_H +#define GLOBAL_CONFIG_H + +#include +#include + +namespace WrtDB { +namespace GlobalConfig { +/** + * WRT database path + */ +inline const char* GetWrtDatabaseFilePath() +{ + return "/opt/dbspace/.wrt.db"; +} + +/** + * WRT device plugin path + */ +inline const char* GetDevicePluginPath() +{ + return "/usr/lib/wrt-plugins"; +} + +/** + * WRT widgets that are downloaded and installed by user + */ +inline const char* GetUserInstalledWidgetPath() +{ + return "/opt/usr/apps"; +} + +/** + * WRT widgets that are preloaded + */ +inline const char* GetUserPreloadedWidgetPath() +{ + return "/usr/apps"; +} + +/** + * WRT widgets that are downloaded and installed by user + */ +inline const char* GetWidgetUserDataPath() +{ + return "/opt/usr/apps"; +} + +/** + * WRT widgets that are downloaded and installed by user + */ +inline const char* GetWidgetSrcPath() +{ + return "/res/wgt"; +} + +/** + * Directory for WebKit local storage files + */ +inline const char* GetPublicVirtualRootPath() +{ + return "/opt/share/widget/data/Public"; +} + +/** + * Directory for WebKit local storage files + */ +inline const char* GetWidgetLocalStoragePath() +{ + return "data/localStorage"; +} + +/** + * Directory for tests data (such as test widgets wgt) + */ +inline const char* GetTestsDataPath() +{ + return "/opt/share/widget/tests"; +} + +/** + * widgets exec path + */ +inline const char* GetUserWidgetExecPath() +{ + return "/bin"; +} + +/** + * widgets private data path + */ +inline const char* GetWidgetPrivateStoragePath() +{ + return "data"; +} + +/** + * widgets private temp data path + */ +inline const char* GetWidgetPrivateTempStoragePath() +{ + return "tmp"; +} + +/** + * widgets desktop files path + */ +inline const char* GetUserWidgetDesktopPath() +{ + return "/opt/share/applications"; +} + +/** + * wrt-client exec path + */ +inline const char* GetWrtClientExec() +{ + return "/usr/bin/wrt-client"; +} + +/** + * wrt-service exec path + */ +inline const char* GetWrtServiceExec() +{ + return "/usr/bin/wrt-service"; +} + +/** + * widgets desktop icon path + */ +inline const char* GetUserWidgetDesktopIconPath() +{ + return "/opt/share/icons/default/small"; +} + +/** + * widgets default icon file + */ +inline const char* GetUserWidgetDefaultIconFile() +{ + return "/usr/share/wrt-engine/wrt_widget_default_icon.png"; +} + +inline const char* GetSignatureXmlSchema() +{ + //TODO please rename, this filename is not descriptive enough + return "/usr/share/wrt-engine/schema.xsd"; +} + +/** + * Name of the w3c geolocation feature + */ +inline const char* GetW3CGeolocationFeatureName() +{ + return "http://www.w3.org/TR/geolocation-API/"; +} + +/** + * Prefix of package name for widgets + */ +inline const char* GetPkgnamePrefix() +{ + return "org.tizen."; +} + +/** + * Plugin Configuration Metafile name + */ +inline const char* GetPluginMetafileName() +{ + return "config.xml"; +} + +/** + * Plugin .so prefix + */ +inline const char* GetPluginPrefix() +{ + return "libwrt-plugins-"; +} + +/** + * Plugin .so suffix + */ +inline const char* GetPluginSuffix() +{ + return ".so"; +} + +/** + * WRT device plugins installation required + * File which indicate that new plugins + * are available and should be installed + */ +inline const char* GetPluginInstallInitializerName() +{ + return "/opt/share/widget/plugin-installation-required"; +} + +/** + * File with certificate fingerprints list. + */ + +inline const char* GetFingerprintListFile() +{ + return "/usr/share/wrt-engine/fingerprint_list.xml"; +} + +inline const char* GetFingerprintListSchema() +{ + return "/usr/share/wrt-engine/fingerprint_list.xsd"; +} + +inline const char* GetVCoreDatabaseFilePath() +{ + return "/opt/dbspace/.cert_svc_vcore.db"; +} + +/** + * widgets cookie database file name + */ +inline const char* GetCookieDatabaseFile() +{ + return ".cookie.db"; +} + +inline const char* GetTmpDirPath() +{ + return "/tmp"; +} + +inline const char* GetTizenVersion() +{ + return "2.3"; +} + +inline const char* GetShareDirectoryPath() +{ + return "/opt/share"; +} + +inline const char* GetTempInstallInfoPath() +{ + return "/opt/share/widget/temp_info"; +} + +inline const char* GetWidgetSharedPath() +{ + return "/shared"; +} + +inline const char* GetWidgetDataPath() +{ + return "/data"; +} + +inline const char* GetWidgetTrustedPath() +{ + return "/trusted"; +} + +inline const char* GetWidgetResPath() +{ + return "/res"; +} + +inline const char* GetNPRuntimePluginsPath() +{ +#ifdef __arm__ + return "plugins/arm"; +#else + return "plugins/x86"; +#endif +} + +inline const char* GetBackupDatabaseSuffix() +{ + return ".backup"; +} + +inline const char* GetManifestPath() +{ + return "/opt/share/packages"; +} + +inline const char* GetPreloadManifestPath() +{ + return "/usr/share/packages"; +} + +inline const char* GetRecoveryStatusPath() +{ + return "/usr/share/packages/.recovery/wgt"; +} +} // namespace GlobalConfig +} // namespace WrtDB + +#endif // GLOBAL_CONFIG_H diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/path_builder.h b/modules/widget_dao/include/dpl/wrt-dao-ro/path_builder.h new file mode 100644 index 0000000..4ea6a4f --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/path_builder.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file PathBuilder.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Header file for PathBuilder class. + */ +#ifndef WRT_UTILS_PATHBUILDER_H +#define WRT_UTILS_PATHBUILDER_H + +#include +#include + +namespace WrtDB { +class PathBuilderImpl; + +class PathBuilder : private DPL::Noncopyable +{ + public: + PathBuilder(); + explicit PathBuilder(const std::string& path); + + ~PathBuilder(); + + PathBuilder& Append(const std::string& path); + + PathBuilder& Concat(const std::string& arg); + PathBuilder& Concat(int arg); + + PathBuilder& Reset(); + + bool Empty() const; + + std::string GetFullPath() const; + + private: + PathBuilderImpl* m_impl; +}; +} // namespace WrtDB + +#endif diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/plugin_dao_read_only.h b/modules/widget_dao/include/dpl/wrt-dao-ro/plugin_dao_read_only.h new file mode 100644 index 0000000..3be2441 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/plugin_dao_read_only.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file plugin_dao_read_only.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of plugin dao read only + */ + +#ifndef WRT_SRC_CONFIGURATION_PLUGIN_DAO_READ_ONLY_H_ +#define WRT_SRC_CONFIGURATION_PLUGIN_DAO_READ_ONLY_H_ + +#include +#include +#include +#include +#include + +namespace WrtDB { +typedef std::list PluginHandleList; +typedef std::set PluginHandleSet; +typedef std::list ImplementedObjectsList; +typedef std::shared_ptr PluginHandleSetPtr; + +//TODO make it friend to FeatureDAO or inherit +class PluginDAOReadOnly +{ + public: + enum PluginInstallationState + { + INSTALLATION_DEFAULT, + //when plugin data are up to date and plugin model may be created + INSTALLATION_COMPLETED, + //installation is in progress, some data may not be valid + INSTALLATION_IN_PROGRESS, + //installation not completed due to missing dependency + INSTALLATION_WAITING, + + UNKNOWN_ERROR + }; + + static int ToInt(PluginInstallationState state) + { + return static_cast(state); + } + + static PluginInstallationState ToState(int state) + { + return static_cast(state); + } + + /** + * PluginDAO Exception classes + */ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DatabaseError) + DECLARE_EXCEPTION_TYPE(Base, PluginNotExist) + DECLARE_EXCEPTION_TYPE(Base, PluginInstallationNotCompleted) + }; + + public: + PluginDAOReadOnly(DbPluginHandle pluginHandle); + PluginDAOReadOnly(const std::string &libraryName); + + static PluginHandleList getPluginHandleList(); + static PluginHandleList getRootPluginHandleList(); + + static bool isPluginInstalled(const std::string &libraryName); + static bool isPluginInstalled(DbPluginHandle pluginHandle); + + static PluginHandleSetPtr getPluginHandleByStatus( + PluginInstallationState state); + + static DbPluginHandle getPluginHandleForImplementedObject( + const std::string& objectName); + + static ImplementedObjectsList getImplementedObjects(); + static ImplementedObjectsList getImplementedObjectsForPluginHandle( + DbPluginHandle handle); + + static PluginObjectsDAO::ObjectsPtr getRequiredObjectsForPluginHandle( + DbPluginHandle handle); + + static PluginInstallationState getInstallationStateForHandle( + DbPluginHandle handle); + + DbPluginHandle getPluginHandle() const; + PluginInstallationState getInstallationStatus() const; + std::string getLibraryPath() const; + std::string getLibraryName() const; + PluginHandleSetPtr getLibraryDependencies() const; + + private: + DbPluginHandle m_pluginHandle; + + void checkInstallationCompleted(); +}; +} // namespace WrtDB + +#endif /* WRT_SRC_CONFIGURATION_PLUGIN_DAO_READ_ONLY_H_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/property_dao_read_only.h b/modules/widget_dao/include/dpl/wrt-dao-ro/property_dao_read_only.h new file mode 100644 index 0000000..88e308a --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/property_dao_read_only.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * property_dao_read_only.h + * + * Created on: Nov 16, 2011 + * Author: Krzysztof Jackiewicz(k.jackiewicz@samsung.com) + */ + +#ifndef PROPERTY_DAO_READ_ONLY_H_ +#define PROPERTY_DAO_READ_ONLY_H_ + +#include +#include +#include +#include +#include + +namespace WrtDB { +namespace PropertyDAOReadOnly { +typedef DPL::String WidgetPropertyKey; +typedef DPL::OptionalString WidgetPropertyValue; + +typedef std::list WidgetPropertyKeyList; + +struct WidgetPreferenceRow { + int appId; + TizenAppId tizen_appid; + WidgetPropertyKey key_name; + WidgetPropertyValue key_value; + DPL::OptionalInt readonly; +}; + +typedef std::list WidgetPreferenceList; + +/** + * PropertyDAO Exception classes + */ +class Exception +{ + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DatabaseError) + DECLARE_EXCEPTION_TYPE(Base, ReadOnlyProperty) +}; + +//deprecated +/* This method checks read only flag for given property + */ +DPL::OptionalInt CheckPropertyReadFlag(DbWidgetHandle widgetHandle, + const WidgetPropertyKey &key) +__attribute__((deprecated)); + +/* This method checks read only flag for given property + */ +DPL::OptionalInt CheckPropertyReadFlag(TizenAppId tzAppid, + const WidgetPropertyKey &key); + +/* This method gets widget property key list + */ +WidgetPropertyKeyList GetPropertyKeyList(TizenAppId tzAppid); + +//deprecated +/* This method gets widget property list + */ +WidgetPreferenceList GetPropertyList(DbWidgetHandle widgetHandle) +__attribute__((deprecated)); + +/* This method gets widget property list + */ +WidgetPreferenceList GetPropertyList(TizenAppId tzAppid); + +/* This method get widget property value + */ +WidgetPropertyValue GetPropertyValue(TizenAppId tzAppid, + const WidgetPropertyKey &key); +} // PropertyDAOReadOnly +} // namespace WrtDB + +#endif /* PROPERTY_DAO_READ_ONLY_H_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/webruntime_database.h b/modules/widget_dao/include/dpl/wrt-dao-ro/webruntime_database.h new file mode 100644 index 0000000..67c88a9 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/webruntime_database.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file webruntime_database.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of webruntime database + */ +#ifndef WRT_ENGINE_SRC_CONFIGURATION_WEBRUNTIME_DATABASE_H +#define WRT_ENGINE_SRC_CONFIGURATION_WEBRUNTIME_DATABASE_H + +#include +#include + +extern DPL::Mutex g_wrtDbQueriesMutex; + +#define WRT_DB_INTERNAL(tlsCommand, InternalType, interface) \ + static DPL::ThreadLocalVariable *tlsCommand##Ptr = NULL; \ + { \ + DPL::Mutex::ScopedLock lock(&g_wrtDbQueriesMutex); \ + if (!tlsCommand##Ptr) { \ + static DPL::ThreadLocalVariable tmp; \ + tlsCommand##Ptr = &tmp; \ + } \ + } \ + DPL::ThreadLocalVariable &tlsCommand = *tlsCommand##Ptr; \ + if (tlsCommand.IsNull()) { tlsCommand = InternalType(interface); } + +#define WRT_DB_SELECT(name, type, interface) WRT_DB_INTERNAL(name, \ + type::Select, \ + interface) + +#define WRT_DB_INSERT(name, type, interface) WRT_DB_INTERNAL(name, \ + type::Insert, \ + interface) + +#define WRT_DB_UPDATE(name, type, interface) WRT_DB_INTERNAL(name, \ + type::Update, \ + interface) + +#define WRT_DB_DELETE(name, type, interface) WRT_DB_INTERNAL(name, \ + type::Delete, \ + interface) + +#endif // WRT_ENGINE_SRC_CONFIGURATION_WEBRUNTIME_DATABASE_H diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/widget_config.h b/modules/widget_dao/include/dpl/wrt-dao-ro/widget_config.h new file mode 100644 index 0000000..c452814 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/widget_config.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file widget_config.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Implementation file for widget config. + */ +#ifndef SRC_DOMAIN_WIDGET_CONFIG_H +#define SRC_DOMAIN_WIDGET_CONFIG_H + +#include +#include + +#include +#include +#include + +namespace WrtDB { +namespace WidgetConfig { +inline std::string GetWidgetBasePath(DPL::String tzPkgId) +{ + return PathBuilder() + .Append(GlobalConfig::GetWidgetUserDataPath()) + .Append(DPL::ToUTF8String(tzPkgId)) + .GetFullPath(); +} + +inline std::string GetWidgetWebLocalStoragePath(DPL::String tzPkgId) +{ + return PathBuilder(GetWidgetBasePath(tzPkgId)) + .Append(GlobalConfig::GetWidgetLocalStoragePath()) + .GetFullPath(); +} + +inline std::string GetWidgetPersistentStoragePath(DPL::String tzPkgId) +{ + return PathBuilder(GetWidgetBasePath(tzPkgId)) + .Append(GlobalConfig::GetWidgetPrivateStoragePath()) + .GetFullPath(); +} + +inline std::string GetWidgetTemporaryStoragePath(DPL::String tzPkgId) +{ + return PathBuilder(GetWidgetBasePath(tzPkgId)) + .Append(GlobalConfig::GetWidgetPrivateTempStoragePath()) + .GetFullPath(); +} + +inline std::string GetWidgetDesktopFilePath(DPL::String tzPkgId) +{ + return PathBuilder() + .Append(GlobalConfig::GetUserWidgetDesktopPath()) + .Append(DPL::ToUTF8String(tzPkgId)) + .Concat(".desktop") + .GetFullPath(); +} + +inline std::string GetWidgetSharedStoragePath(DPL::String tzPkgId) +{ + return PathBuilder() + .Append(GlobalConfig::GetWidgetUserDataPath()) + .Append(DPL::ToUTF8String(tzPkgId)) + .Concat(GlobalConfig::GetWidgetSharedPath()) + .GetFullPath(); +} + +inline std::string GetWidgetSharedDataStoragePath(DPL::String tzPkgId) +{ + return PathBuilder(GetWidgetSharedStoragePath(tzPkgId)) + .Concat(GlobalConfig::GetWidgetDataPath()) + .GetFullPath(); +} + +inline std::string GetWidgetSharedTrustedStoragePath(DPL::String tzPkgId) +{ + return PathBuilder(GetWidgetSharedStoragePath(tzPkgId)) + .Concat(GlobalConfig::GetWidgetTrustedPath()) + .GetFullPath(); +} + +inline std::string GetWidgetSharedResStoragePath(DPL::String tzPkgId) +{ + return PathBuilder(GetWidgetSharedStoragePath(tzPkgId)) + .Concat(GlobalConfig::GetWidgetResPath()) + .GetFullPath(); +} + +inline std::string GetWidgetNPRuntimePluginsPath(const DPL::String& tzPkgId) +{ + return PathBuilder(GetWidgetBasePath(tzPkgId)) + .Concat(GlobalConfig::GetWidgetSrcPath()) + .Append(GlobalConfig::GetNPRuntimePluginsPath()) + .GetFullPath(); +} +} // namespace WidgetConfig +} // namespace WrtDB + +#endif diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_read_only.h b/modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_read_only.h new file mode 100755 index 0000000..c82995d --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_read_only.h @@ -0,0 +1,698 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of widget dao class. + * + * @file widget_dao_read_only.h + * @author Yang Jie (jie2.yang@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of widget dao + */ + +#ifndef _WRT_SRC_CONFIGURATION_WIDGET_DAO_READ_ONLY_H_ +#define _WRT_SRC_CONFIGURATION_WIDGET_DAO_READ_ONLY_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +enum CertificateSource { + SIGNATURE_AUTHOR = 0, + SIGNATURE_DISTRIBUTOR = 1, + SIGNATURE_DISTRIBUTOR2 = 2, + SIGNATURE_UNKNOWN = 3 +}; + +struct WidgetLocalizedInfo +{ + DPL::OptionalString name; + DPL::OptionalString shortName; + DPL::OptionalString description; + DPL::OptionalString license; + DPL::OptionalString licenseHref; +}; + +/** + * CertificateData + * A structure to hold certificate fingerprints. + */ +struct WidgetCertificateData +{ + enum Owner { AUTHOR, DISTRIBUTOR, DISTRIBUTOR2, UNKNOWN }; + enum Type { ROOT, ENDENTITY }; + + // type of signature: author/distributor + Owner owner; + // indicates whether this is ca certificate + Type type; + + // chain id number: relative BASE, where BASE is signatureBASE.xml + int chainId; + // certificate fingerprint digested by md5 + std::string strMD5Fingerprint; + // certificate fingerprint digestef by sha1 + std::string strSHA1Fingerprint; + // Common name field in certificate + DPL::String strCommonName; + + bool operator== (const WidgetCertificateData& certData) const + { + return certData.chainId == chainId && + certData.owner == owner && + certData.strCommonName == strCommonName && + certData.strMD5Fingerprint == strMD5Fingerprint && + certData.strSHA1Fingerprint == strSHA1Fingerprint; + } +}; + +typedef std::list WidgetCertificateDataList; + +typedef DPL::String Locale; +typedef std::set LocaleSet; +typedef std::list ExternalLocationList; + +/** + * WidgetRegisterInfo + * A structure to hold widget's information needed to be registered. + * @see WidgetConfigurationInfo + */ +struct WidgetRegisterInfo +{ + struct LocalizedIcon : public ConfigParserData::Icon + { + LocalizedIcon(const ConfigParserData::Icon& icon, + const LocaleSet& _availableLocales) : + ConfigParserData::Icon(icon), + availableLocales(_availableLocales) + {} + + LocaleSet availableLocales; + }; + + struct StartFileProperties + { + DPL::String encoding; + DPL::String type; + }; + + typedef std::map StartFilePropertiesForLocalesMap; + struct LocalizedStartFile + { + DPL::String path; + StartFilePropertiesForLocalesMap propertiesForLocales; + }; + + typedef std::list LocalizedIconList; + typedef std::list LocalizedStartFileList; + struct LocalizationData + { + LocalizedIconList icons; + LocalizedStartFileList startFiles; + }; + + //Constructor + WidgetRegisterInfo() : + webAppType(APP_TYPE_UNKNOWN), + configInfo(), + packagingType(PKG_TYPE_UNKNOWN) + {} + + WidgetType webAppType; + DPL::OptionalString guid; + DPL::OptionalString version; + DPL::OptionalString minVersion; + std::string baseFolder; + ConfigParserData configInfo; + LocalizationData localizationData; + + TizenPkgId tzPkgid; + TizenAppId tzAppid; + TizenAppId tzBackupAppid; + + time_t installedTime; + PackagingType packagingType; + EncryptedFileList encryptedFiles; + ExternalLocationList externalLocations; + DPL::OptionalString widgetInstalledPath; +}; + +typedef std::list CertificateChainList; +class IWidgetSecurity +{ + public: + virtual ~IWidgetSecurity(); + + virtual const WidgetCertificateDataList& getCertificateList() const = 0; + + virtual bool isRecognized() const = 0; + + virtual bool isDistributorSigned() const = 0; + + virtual void getCertificateChainList(CertificateChainList& list, + CertificateSource source) const = 0; +}; + +/** + * WidgetAuthorInfo. + * Structure to hold the information of widget's author. + */ +struct WidgetAuthorInfo +{ + DPL::OptionalString name; + DPL::OptionalString email; + DPL::OptionalString href; +}; + +typedef std::list WidgetCertificateCNList; +typedef std::list LanguageTagList; +typedef std::list HostList; +typedef std::list FingerPrintList; + +class WidgetDAOReadOnly +{ + public: + /** + * WidgetDAO Exception classes + */ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DatabaseError) + DECLARE_EXCEPTION_TYPE(Base, ReadOnlyProperty) + DECLARE_EXCEPTION_TYPE(Base, GUIDisNull) + DECLARE_EXCEPTION_TYPE(Base, UnexpectedEmptyResult) + DECLARE_EXCEPTION_TYPE(Base, WidgetNotExist) + DECLARE_EXCEPTION_TYPE(Base, AlreadyRegistered) + }; + + protected: + DbWidgetHandle m_widgetHandle; + + public: + struct WidgetLocalizedIconRow + { + int appId; + int iconId; + DPL::String widgetLocale; + }; + typedef std::list WidgetLocalizedIconList; + + struct WidgetIconRow + { + int iconId; + int appId; + DPL::String iconSrc; + DPL::OptionalInt iconWidth; + DPL::OptionalInt iconHeight; + }; + typedef std::list WidgetIconList; + + struct WidgetStartFileRow + { + int startFileId; + int appId; + DPL::String src; + }; + typedef std::list WidgetStartFileList; + + struct WidgetLocalizedStartFileRow + { + int startFileId; + int appId; + DPL::String widgetLocale; + DPL::String type; + DPL::String encoding; + }; + typedef std::list LocalizedStartFileList; + + /** + * This is a constructor. + * + * @param[in] widgetHandle application id of widget. + */ + WidgetDAOReadOnly(DbWidgetHandle widgetHandle); + WidgetDAOReadOnly(DPL::OptionalString widgetGUID); + WidgetDAOReadOnly(WrtDB::TizenAppId tzAppid); + + /** + * Destructor + */ + virtual ~WidgetDAOReadOnly(); + + /** + * This method returns widget handle(m_widgetHandle). + * + * @return widget handle(m_widgetHandle). + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + DbWidgetHandle getHandle() const; + static DbWidgetHandle getHandle(const WidgetGUID GUID); + static DbWidgetHandle getHandle(const DPL::String tzAppId); + static DbWidgetHandle getHandleByPkgId(const DPL::String pkgId); + + /** + * This method Returns tizen application id for the specified web application + * @return TizenAppId + */ + TizenAppId getTzAppId() const DPL_DEPRECATED_WITH_MESSAGE("Use getTizenAppId"); + static TizenAppId getTzAppId(const WidgetGUID GUID) DPL_DEPRECATED_WITH_MESSAGE("Use getTizenAppId"); + static TizenAppId getTzAppId(const DbWidgetHandle handle) DPL_DEPRECATED_WITH_MESSAGE("Use getTizenAppId"); + static TizenAppId getTzAppId(const TizenPkgId tizenPkgId) DPL_DEPRECATED_WITH_MESSAGE("Use getTizenAppId"); + TizenAppId getTizenAppId() const; + static TizenAppId getTizenAppId(const WidgetGUID GUID); + static TizenAppId getTizenAppId(const DbWidgetHandle handle); + static TizenAppId getTizenAppId(const TizenPkgId tizenPkgId); + + /** + * This method returns list of installed tizen application id + * @return TizenAppIdList + */ + static TizenAppIdList getTizenAppidList() DPL_DEPRECATED_WITH_MESSAGE("Use getTizenAppIdList"); + static TizenAppIdList getTizenAppIdList(); + static std::list getTzAppIdList(const TizenPkgId tzPkgid); + + /** + * Returns TizenPkgId for the specified widget + * + * @return TizenPkgId; + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + + TizenPkgId getTzPkgId() const DPL_DEPRECATED_WITH_MESSAGE("Use getTizenPkgId"); + static TizenPkgId getTzPkgId(const DbWidgetHandle handle) DPL_DEPRECATED_WITH_MESSAGE("Use getTizenPkgId"); + static TizenPkgId getTzPkgId(const TizenAppId tzAppid) DPL_DEPRECATED_WITH_MESSAGE("Use getTizenPkgId"); + TizenPkgId getTizenPkgId() const; + static TizenPkgId getTizenPkgId(const DbWidgetHandle handle); + static TizenPkgId getTizenPkgId(const TizenAppId tzAppid); + + /** + * This method returns list of tizen package list of installed packages + * @return list of TizenPkgIdList of installed packages + */ + static TizenPkgIdList getTizenPkgidList() DPL_DEPRECATED_WITH_MESSAGE("Use getTizenPkgIdList"); + static TizenPkgIdList getTizenPkgIdList(); + + /** + * This method returns the root directory of widget resource. + * + * @return path name of root directory. + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + virtual DPL::String getPath() const; + + DPL::String getFullPath() const; + + /** + * This method returns the preferred size of the widget, + * including width and height. + * + * @see DbWidgetSize + * @return An structure type variable to hold widget's size. + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching + * DB table. + */ + DbWidgetSize getPreferredSize() const; + + /** + * This method returns the type of the widget. + * + * @return WidgetType + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching + * records in DB table. + */ + WidgetType getWidgetType() const; + + /** + * This method returns the id of the widget. + * + * @return widget id + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + WidgetGUID getGUID() const; + + /** + * This method returns the defaultlocale for the widget. + * + * @return defaultlocale + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + DPL::OptionalString getDefaultlocale() const; + + /** + * This method returns list of localized icons files; + * + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + WidgetLocalizedIconList getLocalizedIconList() const; + + /** + * This method returns list of icons files; + * + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + WidgetIconList getIconList() const; + + /** + * This method returns list of localized start files; + * + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + LocalizedStartFileList getLocalizedStartFileList() const; + + /** + * This method returns list of start files; + * + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + WidgetStartFileList getStartFileList() const; + + /** + * @param[out] outAccessInfoList list filled with access info structures + */ + void getWidgetAccessInfo(WidgetAccessInfoList& outAccessInfoList) const; + void getWidgetAllowNavigationInfo( + WidgetAllowNavigationInfoList& allowNavigationInfoList) const; + + /** + * This method returns window mode of widget. + * + * @return window modes of widget + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + WindowModeList getWindowModes() const; + + /** + * This method returns the version of the widget. + * + * @return version of widget + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + DPL::OptionalString getVersion() const; + + /** + * This method is used as a getter for csp policy of widget. It should be + * provided in configuration file. + * @return global csp policy for widget + */ + DPL::OptionalString getCspPolicy() const; + + /** + * This method is used as a getter for report only csp policy of widget. + * It may be provided in configuration file. + * @return global csp report only policy for widget + */ + DPL::OptionalString getCspPolicyReportOnly() const; + + /** + * This method returns list filed with Common Name entries from certificate. + * + * @return Common Name of Distribuotor End Entity certificate. + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + WidgetCertificateCNList getKeyCommonNameList( + WidgetCertificateData::Owner owner, + WidgetCertificateData::Type type) const; + + /** + * given a certificate owner (author / distributor) and type of certificate + * (end entity / ca) + * function returns list of matching fingerprints + */ + FingerPrintList getKeyFingerprints( + WidgetCertificateData::Owner owner, + WidgetCertificateData::Type type) const; + + /* + * This method gets certificate data list for a widget from database. + */ + WidgetCertificateDataList getCertificateDataList() const; + + /** + * This method returns a list of widget features. + * + * @see WidgetFeature + * @see FreeFeatureList() + * @return list of widget features, type of list element is structure + * WidgetFeature + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + DbWidgetFeatureSet getFeaturesList() const; + + /** + * This method checks whether widget has specified feature. + * + * @return true if has, false if has not + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + */ + bool hasFeature(const std::string& featureName) const; + + /** + * This method gets if widget needs webkit plugins enabled + * + * @return true: widget needs webkit plugins enabled + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + bool getWebkitPluginsRequired() const; + + /** + * This method returns a list of all the installed widgets. + * + * @return list of installed widgets. + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + static DbWidgetDAOReadOnlyList getWidgetList(); + + /** + * This method gets author's infomation of a widget which is parsed from + * configiration document. + * + * @see WidgetAuthorInfo + * @param[out] pAuthorInfo + * @return true if succeed, false if fail. + */ + WidgetAuthorInfo getAuthorInfo() const; + + /** + * This method gets author's name of a widget which is parsed from + * configiration document. + * + * @param[out] pAuthorInfo + * @return author's name. + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + DPL::OptionalString getAuthorName() const; + + /** + * This method gets author's email of a widget which is parsed from + * configiration document. + * + * @param[out] pAuthorInfo + * @return author's email. + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + DPL::OptionalString getAuthorEmail() const; + + /** + * This method gets author's email of a widget which is parsed from + * configiration document. + * + * @param[out] pAuthorInfo + * @return author's email. + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + DPL::OptionalString getAuthorHref() const; + + /** + * This method returns minimum version of WAC that WRT has to be compliant + * to to run this widget + * + * @return Minimum version + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + DPL::OptionalString getMinimumWacVersion() const; + + /** + * This method get widget installed time + * + * @return time_t : return widget's install time + */ + time_t getInstallTime() const; + + /** + * This method gets widget base folder. + * + * @return widget base folder. + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching records in + * DB table. + */ + std::string getBaseFolder() const; + + /* This method checks read only flag for given property + */ + DPL::OptionalInt checkPropertyReadFlag( + const PropertyDAOReadOnly::WidgetPropertyKey &key) const; + + /* This method gets widget property key list + */ + PropertyDAOReadOnly::WidgetPropertyKeyList getPropertyKeyList() const; + + /* This method gets widget property list + */ + PropertyDAOReadOnly::WidgetPreferenceList getPropertyList() const; + + /* This method get widget property value + */ + PropertyDAOReadOnly::WidgetPropertyValue getPropertyValue( + const PropertyDAOReadOnly::WidgetPropertyKey &key) const; + + LanguageTagList getLanguageTags() const; + LanguageTagList getIconLanguageTags() const; + + WidgetLocalizedInfo getLocalizedInfo(const DPL::String& languageTag) const; + + bool getBackSupported() const; + + static bool isWidgetInstalled(DbWidgetHandle handle); + static bool isWidgetInstalled(const TizenAppId & tzAppId); + + /* This method get path of the splash image. + * + * @return path of the widget's splash image + */ + DPL::OptionalString getSplashImgSrc() const; + + ExternalLocationList getWidgetExternalLocations() const; + + /* + * Default value is required to keep compatibility with + * wrt-installer and wrt. + */ + CertificateChainList getWidgetCertificate( + CertificateSource source = SIGNATURE_DISTRIBUTOR) const; + + void getWidgetSettings(WidgetSettings& outWidgetSettings) const; + + /** + * This method gets application control list that define AUL value + * + * @return See above comment + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + */ + void getAppControlList( + WidgetAppControlList& outAppControlList) const; + + /** + * This method returns the type of the package. + * + * @return PackagingType + * @exception WRT_CONF_ERR_EMDB_FAILURE - Fail to query DB table. + * @exception WRT_CONF_ERR_EMDB_NO_RECORD - Can not find matching + * records in DB table. + */ + PackagingType getPackagingType() const; + + void getEncryptedFileList(EncryptedFileList& filesList) const; + + /** + * This method returns widget's background page filename. + * + * @return Name of file containing background page + */ + DPL::OptionalString getBackgroundPage() const; + + /** + * @brief generateTizenId generates new package id + * + * If widget do not supplies it's own tizen package id, this method can be + * used, + * although it should be removed in future. + * + * @return new tizen package id + */ + static TizenPkgId generatePkgId(); + static TizenPkgId generateTizenId() + { + return generatePkgId(); + } + + /** + * This method returns widget's installed path + * + * @return path of widget installed + */ + DPL::OptionalString getWidgetInstalledPath() const; + PrivilegeList getWidgetPrivilege() const; + WidgetSecurityModelVersion getSecurityModelVersion() const; + +}; +} // namespace WrtDB + +#endif // _WRT_SRC_CONFIGURATION_WIDGET_DAO_READ_ONLY_H_ + diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_types.h b/modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_types.h new file mode 100644 index 0000000..6d6e171 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_types.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file widget_dao_types.h + * @author Leerang Song (leerang.song@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of + * common data types forwidget database. + */ +#ifndef _WIDGET_DAO_TYPES_H_ +#define _WIDGET_DAO_TYPES_H_ + +#include +#include +#include +#include + +namespace WrtDB { + +enum Feature +{ + FEATURE_START = 0, + FEATURE_GEOLOCATION = 0, + FEATURE_WEB_NOTIFICATION, + FEATURE_USER_MEDIA, + FEATURE_FULLSCREEN_MODE, + FEATURE_WEB_DATABASE, + FEATURE_CAMERA, + FEATURE_AUDIO_RECORDER, + FEATURE_END +}; +extern const std::map g_W3CPrivilegeTextMap; +} // namespace WrtDB + +#endif // _WIDGET_DAO_TYPES_H_ diff --git a/modules/widget_dao/include/dpl/wrt-dao-ro/wrt_db_types.h b/modules/widget_dao/include/dpl/wrt-dao-ro/wrt_db_types.h new file mode 100644 index 0000000..1702433 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-ro/wrt_db_types.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * + * @file wrt_db_types.h + * @author Krzysztof Jackiewicz + * @version 1.0 + * @brief This file contains the declaration of common data types for wrtdb + */ +#ifndef _WRT_DB_TYPES_H_ +#define _WRT_DB_TYPES_H_ + +#include + +typedef WrtDB::DbWidgetHandle WidgetHandle; +typedef WrtDB::DbWidgetHandleList WidgetHandleList; +typedef WrtDB::DbWidgetDAOReadOnlyList WidgetDAOReadOnlyList; + +typedef WrtDB::DbWidgetFeature WidgetFeature; +typedef WrtDB::DbWidgetFeatureSet WidgetFeatureSet; + +typedef WrtDB::DbWidgetSize WidgetSize; +typedef WrtDB::DbPluginHandle PluginHandle; + +#endif diff --git a/modules/widget_dao/include/dpl/wrt-dao-rw/feature_dao.h b/modules/widget_dao/include/dpl/wrt-dao-rw/feature_dao.h new file mode 100644 index 0000000..6ee312a --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-rw/feature_dao.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of feature dao class. + * + * @file feature_dao.h + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of feature dao + */ +#ifndef _FEATURE_DAO_H +#define _FEATURE_DAO_H + +#include + +namespace WrtDB { +namespace FeatureDAO { +FeatureHandle RegisterFeature(const PluginMetafileData::Feature &feature, + const DbPluginHandle pluginHandle); +void UnregisterFeature(FeatureHandle featureHandle); +} // namespace FeatureDB +} // namespace WrtDB + +#endif /* _FEATURE_DAO_H */ + diff --git a/modules/widget_dao/include/dpl/wrt-dao-rw/plugin_dao.h b/modules/widget_dao/include/dpl/wrt-dao-rw/plugin_dao.h new file mode 100644 index 0000000..0b53eef --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-rw/plugin_dao.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of plugin dao class. + * + * @file plugin_dao.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of plugin dao + */ + +#ifndef WRT_SRC_CONFIGURATION_PLUGIN_DAO_H_ +#define WRT_SRC_CONFIGURATION_PLUGIN_DAO_H_ + +#include + +namespace WrtDB { +class PluginDAO : public PluginDAOReadOnly +{ + public: + PluginDAO(DbPluginHandle pluginHandle); + PluginDAO(const std::string &libraryName); + + static DbPluginHandle registerPlugin( + const PluginMetafileData& metafile, + const std::string& pluginPath); + + static void registerPluginImplementedObject( + const std::string& objectName, + DbPluginHandle pluginHandle); + + static void registerPluginRequiredObject( + const std::string& objectName, + DbPluginHandle pluginHandle); + + static void registerPluginLibrariesDependencies( + DbPluginHandle plugin, + const PluginHandleSetPtr& dependencies); + + static void setPluginInstallationStatus( + DbPluginHandle, + PluginInstallationState); + + static void unregisterPlugin(DbPluginHandle pluginHandle); +}; +} // namespace WrtDB + +#endif /* WRT_SRC_CONFIGURATION_PLUGIN_DAO_H_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-rw/property_dao.h b/modules/widget_dao/include/dpl/wrt-dao-rw/property_dao.h new file mode 100644 index 0000000..7e3f215 --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-rw/property_dao.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file property_dao.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of property dao + */ + +#ifndef WRT_SRC_CONFIGURATION_PROPERTY_DAO_H_ +#define WRT_SRC_CONFIGURATION_PROPERTY_DAO_H_ + +#include + +namespace WrtDB { +struct WidgetRegisterInfo; //forward declaration + +namespace PropertyDAO { +void RemoveProperty(TizenAppId tzAppid, + const PropertyDAOReadOnly::WidgetPropertyKey &key); + +//deprecated +/* This method sets widget property + */ +void SetProperty(DbWidgetHandle widgetHandle, + const PropertyDAOReadOnly::WidgetPropertyKey &key, + const PropertyDAOReadOnly::WidgetPropertyValue &value, + bool readOnly = false) +__attribute__((deprecated)); + +/* This method sets widget property + */ +void SetProperty(TizenAppId tzAppid, + const PropertyDAOReadOnly::WidgetPropertyKey &key, + const PropertyDAOReadOnly::WidgetPropertyValue &value, + bool readOnly = false); + +/* This method registers properties for widget. + * Properties unregistering is done via "delete cascade" mechanism in SQL + */ +void RegisterProperties(DbWidgetHandle widgetHandle, TizenAppId tzAppid, + const WidgetRegisterInfo ®Info); +} // namespace PropertyDAO +} // namespace WrtDB + +#endif /* WRT_SRC_CONFIGURATION_PROPERTY_DAO_H_ */ diff --git a/modules/widget_dao/include/dpl/wrt-dao-rw/widget_dao.h b/modules/widget_dao/include/dpl/wrt-dao-rw/widget_dao.h new file mode 100755 index 0000000..d205ccf --- /dev/null +++ b/modules/widget_dao/include/dpl/wrt-dao-rw/widget_dao.h @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of widget dao class. + * + * @file widget_dao.h + * @author Yang Jie (jie2.yang@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of widget dao + */ +#ifndef WIDGET_DAO_H +#define WIDGET_DAO_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace WrtDB { +class WidgetDAO : public WidgetDAOReadOnly +{ + public: + typedef std::list LanguageTagsList; + + WidgetDAO(DPL::OptionalString widgetGUID); + WidgetDAO(DPL::String tzAppId); + + /** + * Destructor + */ + virtual ~WidgetDAO(); + + /** + * This method registers the widget information in the DB when it is + * installed. + * + * @see WidgetRegisterInfo + * @see UnRegisterWidget() + * @param[in] TizenAppId Widget app id that will be registered. + * @param[in] pWidgetRegisterInfo Specified the widget's information + * needed to be registered. + * @param[in] widgetSecurity Widget's security certificates. + */ + static void registerWidget( + const TizenAppId& tzAppId, + const WidgetRegisterInfo &widgetRegInfo, + const IWidgetSecurity &widgetSecurity); + + static void registerService( + const ConfigParserData::ServiceAppInfo &serviceAppInfo, + const WidgetRegisterInfo &widgetRegInfo, + const IWidgetSecurity &widgetSecurity); + + /** + * @brief registerWidgetGenerateTizenId Registers widget with auto-generated + * tizen id + * + * This function is disadviced and should be used only in tests. + * Function is not thread-safe. + * + * @param pWidgetRegisterInfo registeration information + * @param widgetSecurity Widget's security certificates. + * @return tzAppId generated + */ + static TizenAppId registerWidgetGeneratePkgId( + const WidgetRegisterInfo &pWidgetRegisterInfo, + const IWidgetSecurity &widgetSecurity); + + static void updateTizenAppId(const TizenAppId & fromAppId, + const TizenAppId & toAppId); + /** + * This method removes a widget's information from EmDB. + * + * @see RegisterWidget() + * @param[in] tzAppId widgets name to be unregistered + */ + static void unregisterWidget(const TizenAppId & tzAppId); + + /* This method removes widget property + */ + void removeProperty(const PropertyDAOReadOnly::WidgetPropertyKey &key); + + /** + * @brief registerExternalLocations Removes rows from + * WidgetExternalLocations + */ + void unregisterAllExternalLocations(); + + /* This method sets widget property + */ + void setProperty(const PropertyDAOReadOnly::WidgetPropertyKey &key, + const PropertyDAOReadOnly::WidgetPropertyValue &value, + bool readOnly = false); + + /* set tzAppId + */ + void setTizenAppId(const DPL::OptionalString& tzAppId); + + /* This function will update of api-feature status. + * If status is true (feature rejected) plugin connected with this + * api feature mustn't be loaded durign widget launch. + */ + void updateFeatureRejectStatus(const DbWidgetFeature &widgetFeature); + + private: + //Methods used during widget registering + static DbWidgetHandle registerWidgetInfo( + const TizenAppId & tzAppId, + const TizenPkgId & tzPkgId, + const std::string & baseFolder, + AppType appType, + PkgType pkgType, + const ConfigParserData &widgetConfigurationInfo, + const IWidgetSecurity &widgetSecurity, + const DPL::Optional handle = + DPL::Optional()); + static void registerWidgetExtendedInfo(DbWidgetHandle widgetHandle, + time_t installedTime, + const DPL::OptionalString & splashImgSrc, const DPL::OptionalString & backgroundPage, + const DPL::OptionalString & widgetInstalledPath); + static void registerWidgetLocalizedInfo( + DbWidgetHandle widgetHandle, + const ConfigParserData::LocalizedDataSet &localizedDataSet); + static void registerWidgetIcons( + DbWidgetHandle widgetHandle, + const WidgetRegisterInfo::LocalizedIconList &icons); + static void registerWidgetStartFile( + DbWidgetHandle widgetHandle, + const WidgetRegisterInfo::LocalizedStartFileList &startFiles); + static void registerWidgetFeatures( + DbWidgetHandle widgetHandle, + const ConfigParserData::FeaturesList &featuresList); + static void registerWidgetPrivilege( + DbWidgetHandle widgetHandle, + const ConfigParserData::PrivilegeList &privilegeList); + static void registerWidgetWindowModes( + DbWidgetHandle widgetHandle, + const ConfigParserData::StringsList &windowModes); + static void registerWidgetWarpInfo( + DbWidgetHandle widgetHandle, + const ConfigParserData::AccessInfoSet &accessInfoSet); + static void registerWidgetAllowNavigationInfo( + DbWidgetHandle widgetHandle, + const ConfigParserData::AllowNavigationInfoList &allowNavigationInfoList); + static void registerWidgetCertificates( + DbWidgetHandle widgetHandle, + const IWidgetSecurity &widgetSecurity); + static void registerCertificatesChains( + DbWidgetHandle widgetHandle, + CertificateSource certificateSource, + const CertificateChainList &list); + static void registerWidgetSettings( + DbWidgetHandle widgetHandle, + const ConfigParserData::SettingsList &settingsList); + static void registerAppControl( + DbWidgetHandle widgetHandle, + const ConfigParserData::AppControlInfoList &appControlList); + static void registerEncryptedResouceInfo( + DbWidgetHandle widgetHandle, + const EncryptedFileList &encryptedFiles); + + /** + * @brief registerExternalLocations Inserts new rows to + * WidgetExternalLocations + * @param externals list of files + */ + static void registerExternalLocations( + DbWidgetHandle widgetHandle, + const ExternalLocationList & + externals); + + static void registerServiceInternal(const ConfigParserData::ServiceAppInfo &serviceAppInfo, + const WidgetRegisterInfo &widgetRegInfo, const IWidgetSecurity &widgetSecurity); + + static void registerWidgetInternal( + const TizenAppId & tzAppId, + const WidgetRegisterInfo &widgetRegInfo, + const IWidgetSecurity &widgetSecurity, + const DPL::Optional handle = + DPL::Optional()); + static void unregisterWidgetInternal(const TizenAppId & tzAppId); + static void insertAppControlInfo(DbWidgetHandle handle, + DPL::String src, + DPL::String operation, + DPL::String uri, + DPL::String mime, + unsigned index, + unsigned disposition); +}; +} // namespace WrtDB + +#endif // WIDGET_DAO_H diff --git a/modules/widget_dao/orm/gen_db_md5.sh b/modules/widget_dao/orm/gen_db_md5.sh new file mode 100755 index 0000000..38587b7 --- /dev/null +++ b/modules/widget_dao/orm/gen_db_md5.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CHECKSUM=`cat ${2} ${3} 2>/dev/null | md5sum 2>/dev/null | cut -d\ -f1 2>/dev/null` +echo "#define DB_CHECKSUM DB_VERSION_${CHECKSUM}" > ${1} +echo "#define DB_CHECKSUM_STR \"DB_VERSION_${CHECKSUM}\"" >> ${1} + diff --git a/modules/widget_dao/orm/orm_generator_wrt.h b/modules/widget_dao/orm/orm_generator_wrt.h new file mode 100644 index 0000000..09ac57e --- /dev/null +++ b/modules/widget_dao/orm/orm_generator_wrt.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ORM_GENERATOR_WRT_H +#define ORM_GENERATOR_WRT_H + +#define ORM_GENERATOR_DATABASE_NAME wrt_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif diff --git a/modules/widget_dao/orm/version_db b/modules/widget_dao/orm/version_db new file mode 100644 index 0000000..7e20d8d --- /dev/null +++ b/modules/widget_dao/orm/version_db @@ -0,0 +1,5 @@ +SQL( + BEGIN TRANSACTION; + CREATE TABLE DB_CHECKSUM (version INT); + COMMIT; +) diff --git a/modules/widget_dao/orm/wrt_db b/modules/widget_dao/orm/wrt_db new file mode 100644 index 0000000..4d31747 --- /dev/null +++ b/modules/widget_dao/orm/wrt_db @@ -0,0 +1,314 @@ +SQL( + PRAGMA foreign_keys = ON; + BEGIN TRANSACTION; +) + +CREATE_TABLE(WidgetInfo) + COLUMN_NOT_NULL(app_id, INTEGER, PRIMARY KEY AUTOINCREMENT) + COLUMN(widget_type, INT, DEFAULT 1) + COLUMN(widget_id, TEXT, DEFAULT '') + COLUMN(widget_version, TEXT, DEFAULT '') + COLUMN(widget_width, INT, DEFAULT 0) + COLUMN(widget_height, INT, DEFAULT 0) + COLUMN(author_name, TEXT, DEFAULT '') + COLUMN(author_email, TEXT, DEFAULT '') + COLUMN(author_href, TEXT, DEFAULT '') + COLUMN(base_folder, TEXT, DEFAULT '') + COLUMN(webkit_plugins_required, TINYINT, DEFAULT 0) + COLUMN(csp_policy, TEXT, DEFAULT '') + COLUMN(csp_policy_report_only, TEXT, DEFAULT '') + COLUMN(wac_signed, INT, DEFAULT 0) + COLUMN(min_version, TEXT, DEFAULT '1.0') + COLUMN_NOT_NULL(back_supported, TINYINT, DEFAULT 0) + COLUMN(access_network, TINYINT, DEFAULT 0) + COLUMN(defaultlocale, TEXT, DEFAULT 0) + COLUMN_NOT_NULL(tizen_pkgid, TEXT, DEFAULT '') + COLUMN_NOT_NULL(tizen_appid, TEXT, DEFAULT 0 UNIQUE) + COLUMN(pkg_type, INT, DEFAULT 0) + COLUMN(security_model_version, INT, DEFAULT 0) +CREATE_TABLE_END() + +SQL( + CREATE INDEX IF NOT EXISTS WidgetInfo_AppidIndex ON WidgetInfo(tizen_appid); +) + +CREATE_TABLE(WidgetCertificate) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(cert_source, INT, CHECK(cert_source between 0 and 2)) + COLUMN_NOT_NULL(encoded_chain, VARCHAR(16000),) + TABLE_CONSTRAINTS( + FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetWindowModes) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(window_mode, VARCHAR(256),) + TABLE_CONSTRAINTS( + FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(LocalizedWidgetInfo) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(widget_locale, TEXT,) + COLUMN(widget_name, TEXT,) + COLUMN(widget_shortname, TEXT,) + COLUMN(widget_description, TEXT,) + COLUMN(widget_license, TEXT,) + COLUMN(widget_license_file, TEXT,) + COLUMN(widget_license_href, TEXT,) + + TABLE_CONSTRAINTS( + PRIMARY KEY (app_id, widget_locale), + FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetExtendedInfo) + COLUMN_NOT_NULL(app_id, INTEGER, PRIMARY KEY) + COLUMN(last_update_time, BIGINT, DEFAULT 0) + COLUMN(install_time, BIGINT, DEFAULT 0) + COLUMN(option_state, INT, DEFAULT 0) + COLUMN(updated, INT, DEFAULT 0) + COLUMN(update_policy, INT, DEFAULT 0) + COLUMN_NOT_NULL(test_widget, INT, CHECK(test_widget between 0 and 1) DEFAULT 0) + COLUMN(splash_img_src, TEXT, DEFAULT '') + COLUMN(background_page, TEXT, DEFAULT '') + COLUMN(installed_path, TEXT, DEFAULT '') + TABLE_CONSTRAINTS( + FOREIGN KEY(app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetPreference) + COLUMN_NOT_NULL(app_id, INTEGER,) + COLUMN_NOT_NULL(tizen_appid, TEXT, DEFAULT 0) + COLUMN_NOT_NULL(key_name, TEXT,) + COLUMN(key_value, TEXT, DEFAULT '') + COLUMN(readonly, INT, DEFAULT 0) + + TABLE_CONSTRAINTS( + PRIMARY KEY(app_id, key_name), + FOREIGN KEY(app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetFeature) + COLUMN_NOT_NULL(widget_feature_id, INTEGER, primary key autoincrement) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(name, TEXT,) + COLUMN_NOT_NULL(rejected, INT,) + TABLE_CONSTRAINTS( + FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetPrivilege) + COLUMN_NOT_NULL(widget_privilege_id, INTEGER, primary key autoincrement) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(name, TEXT,) + TABLE_CONSTRAINTS( + FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetIcon) + COLUMN_NOT_NULL(icon_id, INTEGER, primary key autoincrement) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(icon_src, TEXT,) + COLUMN(icon_width, INT, DEFAULT 0) + COLUMN(icon_height, INT, DEFAULT 0) + TABLE_CONSTRAINTS( + FOREIGN KEY(app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetLocalizedIcon) + COLUMN_NOT_NULL(app_id, INT,) /* TODO key duplicated for efficiency - ORM doesn't support JOIN */ + COLUMN_NOT_NULL(icon_id, INTEGER,) + COLUMN_NOT_NULL(widget_locale, TEXT,) + TABLE_CONSTRAINTS( + FOREIGN KEY(icon_id) REFERENCES WidgetIcon (icon_id) ON DELETE CASCADE, + PRIMARY KEY(icon_id, widget_locale) + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetStartFile) + COLUMN_NOT_NULL(start_file_id, INTEGER, primary key autoincrement) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(src, TEXT,) + TABLE_CONSTRAINTS( + FOREIGN KEY(app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetLocalizedStartFile) + COLUMN_NOT_NULL(app_id, INT,) /* TODO key duplicated for efficiency - ORM doesn't support JOIN */ + COLUMN_NOT_NULL(start_file_id, INTEGER,) + COLUMN_NOT_NULL(widget_locale, TEXT,) + COLUMN_NOT_NULL(type, TEXT,) + COLUMN_NOT_NULL(encoding, TEXT,) + TABLE_CONSTRAINTS( + FOREIGN KEY(start_file_id) REFERENCES WidgetStartFile (start_file_id) ON DELETE CASCADE, + PRIMARY KEY(start_file_id, widget_locale) + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetExternalLocations) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(path, TEXT,) + TABLE_CONSTRAINTS( + FOREIGN KEY(app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE, + PRIMARY KEY(app_id, path) + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetCertificateFingerprint) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(owner, INT,) + COLUMN_NOT_NULL(chainid, INT,) + COLUMN_NOT_NULL(type, INT,) + COLUMN(md5_fingerprint, TEXT,) + COLUMN(sha1_fingerprint, TEXT,) + COLUMN(common_name, VARCHAR(64),) + + TABLE_CONSTRAINTS( + PRIMARY KEY(app_id, chainid, owner, type) + FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetWARPInfo) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(iri, TEXT,) + COLUMN(subdomain_access, INT, CHECK(subdomain_access between 0 and 1)) + + TABLE_CONSTRAINTS( + PRIMARY KEY(app_id, iri) + FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(WidgetAllowNavigation) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(scheme, TEXT,) + COLUMN_NOT_NULL(host, TEXT,) + + TABLE_CONSTRAINTS( + PRIMARY KEY(app_id, scheme, host) + FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(FeaturesList) + COLUMN_NOT_NULL(FeatureUUID, INTEGER, primary key autoincrement) + COLUMN_NOT_NULL(FeatureName, TEXT, unique) + COLUMN_NOT_NULL(PluginPropertiesId, INT,) + + TABLE_CONSTRAINTS( + FOREIGN KEY (PluginPropertiesId) REFERENCES PluginProperties (PluginPropertiesId) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(PluginProperties) + COLUMN_NOT_NULL(PluginPropertiesId, INTEGER, primary key autoincrement) + COLUMN_NOT_NULL(InstallationState, INTEGER, DEFAULT 0) + COLUMN_NOT_NULL(PluginLibraryName, TEXT, unique) + COLUMN(PluginLibraryPath, TEXT,) +CREATE_TABLE_END() + +CREATE_TABLE(PluginDependencies) + COLUMN_NOT_NULL(PluginPropertiesId, INTEGER, not null) + COLUMN_NOT_NULL(RequiredPluginPropertiesId, INTEGER, not null) + + TABLE_CONSTRAINTS( + FOREIGN KEY (PluginPropertiesId) REFERENCES PluginProperties (PluginPropertiesId) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(PluginImplementedObjects) + COLUMN_NOT_NULL(PluginObject, TEXT, unique) + COLUMN_NOT_NULL(PluginPropertiesId, INTEGER, not null) + + TABLE_CONSTRAINTS( + FOREIGN KEY (PluginPropertiesId) REFERENCES PluginProperties (PluginPropertiesId) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(PluginRequiredObjects) + COLUMN_NOT_NULL(PluginPropertiesId, INTEGER, not null) + COLUMN_NOT_NULL(PluginObject, TEXT, not null) + + TABLE_CONSTRAINTS( + FOREIGN KEY (PluginPropertiesId) REFERENCES PluginProperties (PluginPropertiesId) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(DeviceCapabilities) + COLUMN_NOT_NULL(DeviceCapID, INTEGER, primary key autoincrement) + COLUMN_NOT_NULL(DeviceCapName, TEXT, unique) + COLUMN(DeviceCapDefaultValue, INT,) +CREATE_TABLE_END() + +CREATE_TABLE(FeatureDeviceCapProxy) + COLUMN_NOT_NULL(FeatureUUID, INT, not null) + COLUMN_NOT_NULL(DeviceCapID, INT, not null) + + TABLE_CONSTRAINTS( + FOREIGN KEY (FeatureUUID) REFERENCES FeaturesList (FeatureUUID) ON DELETE CASCADE + FOREIGN KEY (DeviceCapID) REFERENCES DeviceCapabilities (DeviceCapID) ON DELETE CASCADE + PRIMARY KEY(FeatureUUID,DeviceCapID) + ) +CREATE_TABLE_END() + +CREATE_TABLE(OCSPResponseStorage) + COLUMN_NOT_NULL(cert_chain, TEXT, primary key) + COLUMN(end_entity_check, INT,) + COLUMN(ocsp_status, INT,) + COLUMN(next_update_time, BIGINT,) +CREATE_TABLE_END() + +CREATE_TABLE(CRLResponseStorage) + COLUMN_NOT_NULL(distribution_point,TEXT, primary key) + COLUMN_NOT_NULL(crl_body, TEXT,) + COLUMN(next_update_time, BIGINT,) +CREATE_TABLE_END() + +CREATE_TABLE(SettingsList) + COLUMN_NOT_NULL(appId, INT,) + COLUMN_NOT_NULL(settingName, TEXT,) + COLUMN_NOT_NULL(settingValue, TEXT,) + TABLE_CONSTRAINTS( + FOREIGN KEY (appId) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(AppControlInfo) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(execute_index, INT,) + COLUMN_NOT_NULL(src, TEXT,) + COLUMN_NOT_NULL(operation, TEXT,) + COLUMN_NOT_NULL(uri, TEXT,) + COLUMN_NOT_NULL(mime, TEXT,) + COLUMN_NOT_NULL(disposition, TINYINT, DEFAULT 0) + + TABLE_CONSTRAINTS( + PRIMARY KEY(app_id, operation, uri, mime) + FOREIGN KEY(app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +CREATE_TABLE(EncryptedResourceList) + COLUMN_NOT_NULL(app_id, INT,) + COLUMN_NOT_NULL(resource, TEXT,) + COLUMN_NOT_NULL(size, INT,) + + TABLE_CONSTRAINTS( + FOREIGN KEY (app_id) REFERENCES WidgetInfo (app_id) ON DELETE CASCADE + ) +CREATE_TABLE_END() + +SQL( + COMMIT; +) diff --git a/modules/widget_dao/orm/wrt_db_definitions b/modules/widget_dao/orm/wrt_db_definitions new file mode 100644 index 0000000..f2a4a2e --- /dev/null +++ b/modules/widget_dao/orm/wrt_db_definitions @@ -0,0 +1,6 @@ +DATABASE_START(wrt) + +#include "wrt_db" +#include "version_db" + +DATABASE_END() diff --git a/modules/widget_dao/orm/wrt_db_sql_generator.h b/modules/widget_dao/orm/wrt_db_sql_generator.h new file mode 100644 index 0000000..1b69679 --- /dev/null +++ b/modules/widget_dao/orm/wrt_db_sql_generator.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file wrt_db_sql_generator.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL input file from + * database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. + +#include + +#include "wrt_db_definitions" diff --git a/modules/widget_interface_dao/CMakeLists.txt b/modules/widget_interface_dao/CMakeLists.txt new file mode 100644 index 0000000..8acad9b --- /dev/null +++ b/modules/widget_interface_dao/CMakeLists.txt @@ -0,0 +1,45 @@ +SET(TARGET_WIDGET_INTERFACE_DAO_DB "Sqlite3DbWidgetInterface") + +ADD_CUSTOM_COMMAND( OUTPUT .widget_interface.db + COMMAND rm -f ${CMAKE_CURRENT_BINARY_DIR}/.widget_interface.db + COMMAND gcc -Wall -I${PROJECT_SOURCE_DIR}/modules/db/include -I${PROJECT_SOURCE_DIR}/modules/widget_interface_dao/orm -E ${PROJECT_SOURCE_DIR}/modules/widget_interface_dao/orm/widget_interface_db_sql_generator.h | grep --invert-match "^#" > ${CMAKE_CURRENT_BINARY_DIR}/widget_interface_db.sql + COMMAND sqlite3 ${CMAKE_CURRENT_BINARY_DIR}/.widget_interface.db ".read ${CMAKE_CURRENT_BINARY_DIR}/widget_interface_db.sql" || rm -f ${CMAKE_CURRENT_BINARY_DIR}/.widget_interface.db + DEPENDS ${PROJECT_SOURCE_DIR}/modules/widget_interface_dao/orm/widget_interface_db_sql_generator.h ${PROJECT_SOURCE_DIR}/modules/widget_interface_dao/orm/widget_interface_db + ) + +ADD_CUSTOM_TARGET(${TARGET_WIDGET_INTERFACE_DAO_DB} ALL DEPENDS .widget_interface.db) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/widget_interface_db.sql DESTINATION share/wrt-engine/) + +INCLUDE(FindPkgConfig) + +PKG_CHECK_MODULES(WIDGET_INTERFACE_DAO_DEPS + glib-2.0 + REQUIRED) + +SET(WIDGET_INTERFACE_DAO_INCLUDE_DIRS + ${PROJECT_SOURCE_DIR}/modules/widget_interface_dao/include + ${PROJECT_SOURCE_DIR}/modules/widget_interface_dao/orm + ${PROJECT_SOURCE_DIR}/modules/core/include + ${PROJECT_SOURCE_DIR}/modules/db/include + ${PROJECT_SOURCE_DIR}/modules/log/include + ${PROJECT_SOURCE_DIR}/modules/widget_dao/include +) + +SET(WIDGET_INTERFACE_DAO_SOURCES + dao/widget_interface_dao.cpp +) + +INCLUDE_DIRECTORIES(SYSTEM ${WIDGET_INTERFACE_DAO_DEPS_INCLUDE_DIRS} ) +INCLUDE_DIRECTORIES(${WIDGET_INTERFACE_DAO_INCLUDE_DIRS}) + +ADD_LIBRARY(${TARGET_WIDGET_INTERFACE_DAO_LIB} SHARED ${WIDGET_INTERFACE_DAO_SOURCES}) +SET_TARGET_PROPERTIES(${TARGET_WIDGET_INTERFACE_DAO_LIB} PROPERTIES SOVERSION ${API_VERSION} VERSION ${VERSION}) +TARGET_LINK_LIBRARIES(${TARGET_WIDGET_INTERFACE_DAO_LIB} ${TARGET_DPL_EFL} ${TARGET_DPL_DB_EFL} ${TARGET_WRT_DAO_RO_LIB} ${WIDGET_INTERFACE_DAO_DEPS_LIBRARIES}) +ADD_DEPENDENCIES(${TARGET_WIDGET_INTERFACE_DAO_LIB} ${TARGET_WIDGET_INTERFACE_DAO_DB}) + +INSTALL(TARGETS ${TARGET_WIDGET_INTERFACE_DAO_LIB} DESTINATION lib) + +INSTALL(FILES + include/wrt-commons/widget-interface-dao/widget_interface_dao.h + DESTINATION include/dpl-efl/wrt-commons/widget-interface-dao +) diff --git a/modules/widget_interface_dao/dao/widget_interface_dao.cpp b/modules/widget_interface_dao/dao/widget_interface_dao.cpp new file mode 100644 index 0000000..1d66ed8 --- /dev/null +++ b/modules/widget_interface_dao/dao/widget_interface_dao.cpp @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @author Lukasz Marek (l.marek@samsung.com) + * @version 0.1 + * @brief + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "orm_generator_widget_interface.h" + +namespace WidgetInterfaceDB { +using namespace DPL::DB::ORM; +using namespace DPL::DB::ORM::widget_interface; + +#define SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN Try +#define SQL_CONNECTION_EXCEPTION_HANDLER_END(message) \ + Catch(DPL::DB::SqlConnection::Exception::Base) { \ + LogError(message); \ + ReThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError, \ + message); \ + } + +namespace { +DPL::DB::SqlConnection::Flag::Type DATABASE_FLAG = + DPL::DB::SqlConnection::Flag::UseLucene; +DPL::DB::SqlConnection::Flag::Option DATABASE_OPTION = + DPL::DB::SqlConnection::Flag::RW; +const char *KEY_WIDGET_ARG = "widget_arg"; + +const char* const DATABASE_NAME = ".widget_interface.db"; +const char* const DATABASE_FILE_PATH = + "/usr/share/wrt-engine/widget_interface_db.sql"; +const char* const DATABASE_JOURNAL_FILENAME = "-journal"; + +const int APP_UID = 5000; +const int APP_GUID = 5000; +} // anonymous namespace + +WidgetInterfaceDAO::WidgetInterfaceDAO(int widgetHandle) : + m_widgetHandle(widgetHandle), + m_databaseInterface(databaseFileName(widgetHandle), DATABASE_FLAG) +{ + checkDatabase(); + m_databaseInterface.AttachToThread(DATABASE_OPTION); +} + +WidgetInterfaceDAO::~WidgetInterfaceDAO() +{ + m_databaseInterface.DetachFromThread(); +} + +void WidgetInterfaceDAO::checkDatabase() +{ + std::string databaseFile = databaseFileName(m_widgetHandle); + struct stat buffer; + if (stat(databaseFile.c_str(), &buffer) != 0) { + //Create fresh database + LogDebug("Creating database " << databaseFile); + + std::fstream file; + file.open(DATABASE_FILE_PATH, std::ios_base::in); + if (!file) { + ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError, + "Cannot create database. SQL file is missing."); + } + + std::stringstream stream; + stream << file.rdbuf(); + + file.close(); + + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + DPL::DB::SqlConnection con(databaseFile, + DATABASE_FLAG, + DATABASE_OPTION); + con.ExecCommand(stream.str().c_str()); + copyPropertiesFromWrtDatabase(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot create database") + + if(chown(databaseFile.c_str(), APP_UID, APP_GUID) != 0) { + ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError, + "Fail to change uid/guid"); + } + std::string databaseJournal = + databaseFile + DATABASE_JOURNAL_FILENAME; + if(chown(databaseJournal.c_str(), APP_UID, APP_GUID) != 0) { + ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError, + "Fail to change uid/guid"); + } + } +} + +void WidgetInterfaceDAO::copyPropertiesFromWrtDatabase() +{ + WrtDB::WrtDatabase::attachToThreadRO(); + m_databaseInterface.AttachToThread(DPL::DB::SqlConnection::Flag::RW); + + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WrtDB::PropertyDAOReadOnly::WidgetPreferenceList existing = + WrtDB::PropertyDAOReadOnly::GetPropertyList( + WrtDB::WidgetDAOReadOnly::getTizenAppId(m_widgetHandle) + ); + + //save all properties read from config.xml + FOREACH(prop, existing) { + std::string key = DPL::ToUTF8String(prop->key_name); + if (key != KEY_WIDGET_ARG) { + std::string value; + if (!prop->key_value.IsNull()) { + value = DPL::ToUTF8String(*(prop->key_value)); + } + bool readonly = !prop->readonly.IsNull() && (*prop->readonly); + setItem(key, value, readonly, true); + } + } + } + SQL_CONNECTION_EXCEPTION_HANDLER_END( + "Cannot copy properties read from config.xml"); + + WrtDB::WrtDatabase::detachFromThread(); + m_databaseInterface.DetachFromThread(); +} + +void WidgetInterfaceDAO::setItem(const std::string& key, + const std::string& value, + bool readOnly) +{ + setItem(key, value, readOnly, false); +} + +void WidgetInterfaceDAO::setItem(const std::string& key, + const std::string& value, + bool readOnly, + bool fromConfigXml) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + ScopedTransaction tran(&m_databaseInterface); + //check if key exists + Properties::Select select(&m_databaseInterface); + select.Where(Equals(DPL::FromUTF8String(key))); + std::list rows = select.GetRowList(); + + if (rows.empty()) { + Properties::Insert insert(&m_databaseInterface); + Properties::Row row; + row.Set_key(DPL::FromUTF8String(key)); + row.Set_value(DPL::FromUTF8String(value)); + row.Set_readonly(readOnly ? 1 : 0); + row.Set_configxml(fromConfigXml ? 1 : 0); + insert.Values(row); + insert.Execute(); + } else { + Assert(rows.size() == 1); + Properties::Row row = rows.front(); + if (row.Get_readonly() != 0) { + Throw(Exception::LocalStorageValueNoModifableException); + } + row.Set_value(DPL::FromUTF8String(value)); + row.Set_readonly(readOnly ? 1 : 0); + Properties::Update update(&m_databaseInterface); + update.Where(Equals(DPL::FromUTF8String(key))); + update.Values(row); + update.Execute(); + } + tran.Commit(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot set item"); +} + +void WidgetInterfaceDAO::removeItem(const std::string& key) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + Properties::Select select(&m_databaseInterface); + select.Where(Equals(DPL::FromUTF8String(key))); + bool readonly = select.GetSingleValue(); + if (readonly) { + ThrowMsg(Exception::LocalStorageValueNoModifableException, + "Cannot delete item. Item is readonly"); + } + Properties::Delete deleteItem(&m_databaseInterface); + deleteItem.Where(Equals(DPL::FromUTF8String(key))); + deleteItem.Execute(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot delete item"); +} + +DPL::Optional WidgetInterfaceDAO::getValue( + const std::string& key) const +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + Properties::Select select(&m_databaseInterface); + select.Where(Equals(DPL::FromUTF8String(key))); + std::list value = + select.GetValueList(); + if (value.empty()) { + return DPL::Optional(); + } + return DPL::Optional(DPL::ToUTF8String(value.front())); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Not found item"); +} + +void WidgetInterfaceDAO::clear(bool removeReadOnly) +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + Properties::Delete deleteItem(&m_databaseInterface); + if (!removeReadOnly) { + deleteItem.Where(Equals(0)); + } + deleteItem.Execute(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot delete all items"); +} + +size_t WidgetInterfaceDAO::getStorageSize() const +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + Properties::Select select(&m_databaseInterface); + std::list list = + select.GetValueList(); + return list.size(); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot get item count"); +} + +std::string WidgetInterfaceDAO::getKeyByIndex(size_t index) const +{ + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + Properties::Select select(&m_databaseInterface); + select.OrderBy("key"); + std::list list = select.GetValueList(); + if (index >= list.size()) { + Throw(Exception::InvalidArgumentException); + } + for (size_t i = 0; i < index; ++i) { + list.pop_front(); + } + return DPL::ToUTF8String(list.front()); + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot get item count"); +} + +std::string WidgetInterfaceDAO::databaseFileName(int widgetHandle) +{ + using namespace DPL::DB::ORM; + using namespace WrtDB::WidgetConfig; + + WrtDB::WrtDatabase::attachToThreadRO(); + std::stringstream filename; + SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN + { + WrtDB::WidgetDAOReadOnly widgetDAO(widgetHandle); + WrtDB::TizenPkgId pkgid = widgetDAO.getTizenPkgId(); + + filename << GetWidgetPersistentStoragePath(pkgid) + << "/" + << DATABASE_NAME; + } + SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot get item count"); + WrtDB::WrtDatabase::detachFromThread(); + return filename.str(); +} +} // namespace WidgetInterfaceDB diff --git a/modules/widget_interface_dao/include/wrt-commons/widget-interface-dao/widget_interface_dao.h b/modules/widget_interface_dao/include/wrt-commons/widget-interface-dao/widget_interface_dao.h new file mode 100644 index 0000000..8b35344 --- /dev/null +++ b/modules/widget_interface_dao/include/wrt-commons/widget-interface-dao/widget_interface_dao.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @author Lukasz Marek (l.marek@samsung.com) + * @version 0.1 + * @brief + */ + +#ifndef _WIDGET_INTERFACE_DAO_H_ +#define _WIDGET_INTERFACE_DAO_H_ + +#include +#include +#include + +namespace WidgetInterfaceDB { +class WidgetInterfaceDAO +{ + public: + + /** + * WidgetInterfaceDAO Exception classes + */ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DatabaseError) + DECLARE_EXCEPTION_TYPE(Base, LocalStorageValueNoModifableException) + DECLARE_EXCEPTION_TYPE(Base, InvalidArgumentException) + }; + WidgetInterfaceDAO(int widgetHandle); + virtual ~WidgetInterfaceDAO(); + + static std::string databaseFileName(int widgetHandle); + void setItem(const std::string& key, + const std::string& value, + bool readOnly, + bool fromConfigXml); + void setItem(const std::string& key, + const std::string& value, + bool readOnly); + void removeItem(const std::string& key); + DPL::Optional getValue(const std::string& key) const; + void clear(bool removeReadOnly); + size_t getStorageSize() const; + std::string getKeyByIndex(size_t index) const; + + protected: + int m_widgetHandle; + mutable DPL::DB::ThreadDatabaseSupport m_databaseInterface; + + private: + void checkDatabase(); + void copyPropertiesFromWrtDatabase(); +}; +typedef std::unique_ptr WidgetInterfaceDAOPtr; +} +#endif //_WIDGET_INTERFACE_DAO_H_ diff --git a/modules/widget_interface_dao/orm/orm_generator_widget_interface.h b/modules/widget_interface_dao/orm/orm_generator_widget_interface.h new file mode 100644 index 0000000..87a3e05 --- /dev/null +++ b/modules/widget_interface_dao/orm/orm_generator_widget_interface.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ORM_GENERATOR_WIDGET_INTERFACE_H_ +#define ORM_GENERATOR_WIDGET_INTERFACE_H_ + +#define ORM_GENERATOR_DATABASE_NAME widget_interface_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif diff --git a/modules/widget_interface_dao/orm/widget_interface_db b/modules/widget_interface_dao/orm/widget_interface_db new file mode 100644 index 0000000..d33ec48 --- /dev/null +++ b/modules/widget_interface_dao/orm/widget_interface_db @@ -0,0 +1,17 @@ +SQL( + PRAGMA foreign_keys = ON; + BEGIN TRANSACTION; +) + +CREATE_TABLE(Properties) + COLUMN_NOT_NULL(key, TEXT,) + COLUMN_NOT_NULL(value, TEXT,) + COLUMN_NOT_NULL(readonly, INTEGER, check(readonly between 0 and 1)) + COLUMN_NOT_NULL(configxml, INTEGER, check(readonly between 0 and 1) DEFAULT 0) + + TABLE_CONSTRAINTS(unique(key)) +CREATE_TABLE_END() + +SQL( + COMMIT; +) diff --git a/modules/widget_interface_dao/orm/widget_interface_db_definitions b/modules/widget_interface_dao/orm/widget_interface_db_definitions new file mode 100644 index 0000000..85f627d --- /dev/null +++ b/modules/widget_interface_dao/orm/widget_interface_db_definitions @@ -0,0 +1,5 @@ +DATABASE_START(widget_interface) + +#include "widget_interface_db" + +DATABASE_END() diff --git a/modules/widget_interface_dao/orm/widget_interface_db_sql_generator.h b/modules/widget_interface_dao/orm/widget_interface_db_sql_generator.h new file mode 100644 index 0000000..b4ce0b6 --- /dev/null +++ b/modules/widget_interface_dao/orm/widget_interface_db_sql_generator.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file wrt_db_sql_generator.h + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL input file from + * database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. + +#include + +#include "widget_interface_db_definitions" diff --git a/packaging/wrt-commons.spec b/packaging/wrt-commons.spec new file mode 100644 index 0000000..09267f9 --- /dev/null +++ b/packaging/wrt-commons.spec @@ -0,0 +1,145 @@ +#git:framework/web/wrt-commons +Name: wrt-commons +Summary: Wrt common library +Version: 0.2.196_w8 +Release: 1 +Group: Development/Libraries +License: Apache License, Version 2.0 +URL: N/A +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(ecore) +BuildRequires: pkgconfig(appcore-efl) +BuildRequires: pkgconfig(libssl) +BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(db-util) +BuildRequires: pkgconfig(zlib) +BuildRequires: pkgconfig(libpcrecpp) +BuildRequires: pkgconfig(icu-i18n) +BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(libiri) +BuildRequires: pkgconfig(libidn) +BuildRequires: pkgconfig(minizip) +BuildRequires: boost-devel + +%description +Wrt common library + +%package devel +Summary: Wrt common library development headers +Group: Development/Libraries +Requires: %{name} = %{version} +Requires: boost-devel + +%description devel +Wrt common library development headers + +%prep +%setup -q + +%define with_tests 0 +%if "%{WITH_TESTS}" == "ON" || "%{WITH_TESTS}" == "Y" || "%{WITH_TESTS}" == "YES" || "%{WITH_TESTS}" == "TRUE" || "%{WITH_TESTS}" == "1" + %define with_tests 1 +%endif + +%define with_child 0 +%if "%{WITH_CHILD}" == "ON" || "%{WITH_CHILD}" == "Y" || "%{WITH_CHILD}" == "YES" || "%{WITH_CHILD}" == "TRUE" || "%{WITH_CHILD}" == "1" + %define with_child 1 +%endif + +%build +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" + +export LDFLAGS+="-Wl,--rpath=%{_libdir} -Wl,--hash-style=both -Wl,--as-needed" + +cmake . -DVERSION=%{version} \ + -DDPL_LOG="OFF" \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DCMAKE_BUILD_TYPE=%{?build_type:%build_type} \ + %{?WITH_TESTS:-DWITH_TESTS=%WITH_TESTS} \ + %{?WITH_CHILD:-DWITH_CHILD=%WITH_CHILD} +make %{?jobs:-j%jobs} + +%install +mkdir -p %{buildroot}/usr/share/license +cp LICENSE %{buildroot}/usr/share/license/%{name} +%make_install + +%clean +rm -rf %{buildroot} + +%post +mkdir -p /opt/share/widget/system +mkdir -p /opt/share/widget/user +mkdir -p /opt/share/widget/exec +mkdir -p /opt/share/widget/data/Public +mkdir -p /usr/lib/wrt-plugins + +#Don't reset DB when install on QEMU (during other packages building witch GBS) +if [ -z "$EMULATOR_ARCHS" ]; then + if [ -z ${2} ]; then + echo "This is new install of wrt-commons" + echo "Calling /usr/bin/wrt_commons_reset_db.sh" + /usr/bin/wrt_commons_reset_db.sh + else + # Find out old and new version of databases + WRT_OLD_DB_VERSION=`sqlite3 /opt/dbspace/.wrt.db ".tables" | grep "DB_VERSION_"` + WRT_NEW_DB_VERSION=`cat /usr/share/wrt-engine/wrt_db.sql | tr '[:blank:]' '\n' | grep DB_VERSION_` + echo "OLD wrt database version ${WRT_OLD_DB_VERSION}" + echo "NEW wrt database version ${WRT_NEW_DB_VERSION}" + + if [ ${WRT_OLD_DB_VERSION} -a ${WRT_NEW_DB_VERSION} ] + then + if [ ${WRT_NEW_DB_VERSION} = ${WRT_OLD_DB_VERSION} ] + then + echo "Equal database detected so db installation ignored" + else + echo "Calling /usr/bin/wrt_commons_reset_db.sh" + /usr/bin/wrt_commons_reset_db.sh + fi + else + echo "Calling /usr/bin/wrt_commons_reset_db.sh" + /usr/bin/wrt_commons_reset_db.sh + fi + fi +fi + +mkdir -p /usr/etc/ace +mkdir -p /usr/apps/org.tizen.policy + +# Set Smack label for db files +chsmack -a 'wrt-commons::db_wrt' /opt/dbspace/.wrt.db +chsmack -a 'wrt-commons::db_wrt' /opt/dbspace/.wrt.db-journal +chsmack -a 'wrt-commons::db_wrt' /opt/usr/dbspace/.wrt_custom_handler.db +chsmack -a 'wrt-commons::db_wrt' /opt/usr/dbspace/.wrt_custom_handler.db-journal +chsmack -a '*' /opt/usr/dbspace/.wrt_i18n.db +chsmack -a '*' /opt/usr/dbspace/.wrt_i18n.db-journal + +echo "[WRT] wrt-commons postinst done ..." + +%files +%manifest wrt-commons.manifest +%{_libdir}/*.so +%{_libdir}/*.so.* +%{_datadir}/wrt-engine/* +%{_datadir}/license/%{name} +%attr(755,root,root) %{_bindir}/wrt_commons_create_clean_db.sh +%attr(755,root,root) %{_bindir}/wrt_commons_reset_db.sh +%if %{with_tests} + %attr(755,root,root) %{_bindir}/wrt-commons-tests-* + %attr(755,root,root) %{_bindir}/wrt_dao_tests_prepare_db.sh + %attr(755,root,root) %{_bindir}/wrt_db_localization_prepare.sh + %{_datadir}/dbus-1/services/org.tizen.DBusTestService.service + /opt/share/wrt/wrt-commons/tests/* + /opt/share/widget/tests/localization/* +%endif + +%files devel +%{_includedir}/dpl-efl/* +%{_libdir}/pkgconfig/*.pc diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..50227c7 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,30 @@ +# Suppress all warnings; TODO: inhibit only specific warnings per target (TURNED OFF) +#SET(CMAKE_CXX_FLAGS_BACKUP ${CMAKE_CXX_FLAGS}) +#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") + +INCLUDE(CMakeUtils.txt) + +SET(TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +SET(TESTS_COMMON_DIR "${TESTS_DIR}/common") + +WRT_ADD_INTERNAL_DEPENDENCIES( + ${TARGET_DPL_TEST_ENGINE_EFL} +) + +ADD_SUBDIRECTORY(core) +ADD_SUBDIRECTORY(dao) +ADD_SUBDIRECTORY(db) +ADD_SUBDIRECTORY(dbus) +ADD_SUBDIRECTORY(event) +ADD_SUBDIRECTORY(files_localization) +ADD_SUBDIRECTORY(localizationTagsProvider) +ADD_SUBDIRECTORY(utils) +ADD_SUBDIRECTORY(i18n) + +IF(WITH_CHILD) + MESSAGE(STATUS "Additional test subdirectory is being added") + ADD_SUBDIRECTORY(test) +ENDIF(WITH_CHILD) + +# Rollback CXX flags +#SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_BACKUP}) diff --git a/tests/CMakeUtils.txt b/tests/CMakeUtils.txt new file mode 100644 index 0000000..ea9cfb3 --- /dev/null +++ b/tests/CMakeUtils.txt @@ -0,0 +1,178 @@ +# @file CMakeUtils.txt +# @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) +# @author Pawel Sikorski (p.sikorski@samsung.com) +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) +# @version 1.0 +# @brief +# + +# +# Discovers target's INCLUDE_DIRECTORIES and LINK_DIRECTORIES. +# This is done by retrieving the directory target was built in and +# fetching appropriate properties of that directory. +FUNCTION(WRT_INTROSPECT_TARGET PREFIX TARGET_NAME) + GET_TARGET_PROPERTY(LOCATION ${TARGET_NAME} LOCATION) + IF(${LOCATION} STREQUAL "LOCATION-NOTFOUND") + MESSAGE(FATAL_ERROR "Target '${TARGET_NAME}' introspection failed") + ELSE(${LOCATION} STREQUAL "LOCATION-NOTFOUND") + STRING(FIND ${LOCATION} "/" LAST_SLASH_POSITION REVERSE) + STRING(SUBSTRING ${LOCATION} 0 ${LAST_SLASH_POSITION} LOCATION) + + GET_DIRECTORY_PROPERTY(INCLUDE_DIRS DIRECTORY ${LOCATION} INCLUDE_DIRECTORIES) + SET("${PREFIX}_INCLUDE_DIRS" ${INCLUDE_DIRS} PARENT_SCOPE) + + GET_DIRECTORY_PROPERTY(LIBRARY_DIRS DIRECTORY ${LOCATION} LINK_DIRECTORIES) + SET("${PREFIX}_LIBRARY_DIRS" ${LIBRARY_DIRS} PARENT_SCOPE) + ENDIF(${LOCATION} STREQUAL "LOCATION-NOTFOUND") +ENDFUNCTION(WRT_INTROSPECT_TARGET) + +# +# Replacement functions for standard (w/o "WRT_" prefix) CMake functions. +# They store supplied arguments in global properties to assign them to tests. +# Anything added with this functions is used by all targets that are built with +# WRT_TEST_BUILD function. + +# +# Appends directories to global property TESTS_INCLUDE_DIRS which is +# then read by WRT_TEST_BUILD and its content is forwarded to +# command INCLUDE_DIRECTORIES() (for all targets). +FUNCTION(WRT_INCLUDE_DIRECTORIES) + SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_INCLUDE_DIRS ${ARGV}) +ENDFUNCTION(WRT_INCLUDE_DIRECTORIES) + +# +# Appends directories to global property TESTS_LIBRARY_DIRS which is +# then read by WRT_TEST_BUILD and its content is forwarded to +# command LINK_DIRECTORIES() (for all targets). +FUNCTION(WRT_LINK_DIRECTORIES) + SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_LIBRARY_DIRS ${ARGV}) +ENDFUNCTION(WRT_LINK_DIRECTORIES) + +# +# Appends directories to global property TESTS_LIBRARIES which is +# then read by WRT_TEST_BUILD and its content is forwarded to +# command TARGET_LINK_LIBRARIES() (for all targets). +FUNCTION(WRT_TARGET_LINK_LIBRARIES) + SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_LIBRARIES ${ARGV}) +ENDFUNCTION(WRT_TARGET_LINK_LIBRARIES) + +# +# Convenience method that fills TESTS_INCLUDE_DIRS, TESTS_LIBRARY_DIRS +# and TESTS_LIBRARIES with values discovered from introspecting supplied +# targets. +# Function takes arbitrary number of targets. +FUNCTION(WRT_ADD_INTERNAL_DEPENDENCIES) + FOREACH(DEPENDENCY ${ARGV}) + WRT_INTROSPECT_TARGET(prefix ${DEPENDENCY}) + WRT_INCLUDE_DIRECTORIES(${prefix_INCLUDE_DIRS}) + WRT_LINK_DIRECTORIES(${prefix_LIBRARY_DIRS}) + WRT_TARGET_LINK_LIBRARIES(${DEPENDENCY}) + ENDFOREACH(DEPENDENCY) +ENDFUNCTION(WRT_ADD_INTERNAL_DEPENDENCIES) + + +# +# Replacement functions for standard (w/o "WRT_" prefix) CMake functions. +# They store supplied arguments in global properties to assign them to specific +# tests. Properties names are based on the test target name. +# Anything added with this functions is used only by the specified target that +# is built with WRT_TEST_BUILD function. + +# +# Appends directories to global property ${TARGET_NAME}_INCLUDE_DIRS +# which is then read by WRT_TEST_BUILD and its content is forwarded to +# command INCLUDE_DIRECTORIES() (for specified target). +FUNCTION(WRT_TEST_INCLUDE_DIRECTORIES TARGET_NAME) + SET_PROPERTY(GLOBAL APPEND PROPERTY ${TARGET_NAME}_INCLUDE_DIRS ${ARGN}) +ENDFUNCTION(WRT_TEST_INCLUDE_DIRECTORIES) + +# +# Appends directories to global property ${TARGET_NAME}_LIBRARY_DIRS +# which is then read by WRT_TEST_BUILD and its content is forwarded to +# command LINK_DIRECTORIES() (for specified target). +FUNCTION(WRT_TEST_LINK_DIRECTORIES TARGET_NAME) + SET_PROPERTY(GLOBAL APPEND PROPERTY ${TARGET_NAME}_LIBRARY_DIRS ${ARGN}) +ENDFUNCTION(WRT_TEST_LINK_DIRECTORIES) + +# +# Appends directories to global property ${TARGET_NAME}_LIBRARIES +# which is then read by WRT_TEST_BUILD and its content is forwarded to +# command TARGET_LINK_LIBRARIES() (for specified target). +FUNCTION(WRT_TEST_TARGET_LINK_LIBRARIES TARGET_NAME) + SET_PROPERTY(GLOBAL APPEND PROPERTY ${TARGET_NAME}_LIBRARIES ${ARGN}) +ENDFUNCTION(WRT_TEST_TARGET_LINK_LIBRARIES) + +# +# Convenience method that fills ${TARGET_NAME}_INCLUDE_DIRS, +# ${TARGET_NAME}_LIBRARY_DIRS and ${TARGET_NAME}_LIBRARIES with +# values discovered from introspecting supplied targets. +# Function takes arbitrary number of targets. +FUNCTION(WRT_TEST_ADD_INTERNAL_DEPENDENCIES TARGET_NAME) + FOREACH(DEPENDENCY ${ARGN}) + WRT_INTROSPECT_TARGET(prefix ${DEPENDENCY}) + WRT_TEST_INCLUDE_DIRECTORIES(${TARGET_NAME} ${prefix_INCLUDE_DIRS}) + WRT_TEST_LINK_DIRECTORIES(${TARGET_NAME} ${prefix_LIBRARY_DIRS}) + WRT_TEST_TARGET_LINK_LIBRARIES(${TARGET_NAME} ${DEPENDENCY}) + ENDFOREACH(DEPENDENCY) +ENDFUNCTION(WRT_TEST_ADD_INTERNAL_DEPENDENCIES) + +# Functions used to build test targets (proper sources, includes, libs are +# added automatically) +FUNCTION(WRT_TEST_BUILD TARGET_NAME) + SET(SOURCES "${ARGN}") + ADD_EXECUTABLE("${TARGET_NAME}" ${SOURCES}) + + # get include dirs global property + GET_PROPERTY(INCLUDE_DIRS GLOBAL PROPERTY TESTS_INCLUDE_DIRS) + GET_PROPERTY(TEST_INCLUDE_DIRS GLOBAL PROPERTY ${TARGET_NAME}_INCLUDE_DIRS) + INCLUDE_DIRECTORIES( + ${INCLUDE_DIRS} + ${TEST_INCLUDE_DIRS} + ) + + # get library dirs global property + GET_PROPERTY(LIBRARY_DIRS GLOBAL PROPERTY TESTS_LIBRARY_DIRS) + GET_PROPERTY(TEST_LIBRARY_DIRS GLOBAL PROPERTY ${TARGET_NAME}_LIBRARY_DIRS) + LINK_DIRECTORIES( + ${LIBRARY_DIRS} + ${TEST_LIBRARY_DIRS} + ) + + # get link libraries global property + GET_PROPERTY(LINK_LIBRARIES GLOBAL PROPERTY TESTS_LIBRARIES) + GET_PROPERTY(TEST_LIBRARIES GLOBAL PROPERTY ${TARGET_NAME}_LIBRARIES) + TARGET_LINK_LIBRARIES("${TARGET_NAME}" + ${LINK_LIBRARIES} + ${TEST_LIBRARIES} + ) +ENDFUNCTION(WRT_TEST_BUILD) + +FUNCTION(WRT_TEST_INSTALL) + SET_TARGET_PROPERTIES(${ARGV} PROPERTIES + BUILD_WITH_INSTALL_RPATH ON + INSTALL_RPATH_USE_LINK_PATH ON + ) + INSTALL(TARGETS ${ARGV} + DESTINATION bin + PERMISSIONS OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE + ) +ENDFUNCTION(WRT_TEST_INSTALL) + +# Takes arbitrary number of arguments and concatenates them using ':' character. +# Rationale: +# CMake list when converted to a string is joined with ';' character. However, +# GCC takes strings with multiple elements separated with ':' (e.g. list of +# paths). Used typically when generating DB schemas with ORM mechanism. +FUNCTION(WRT_CONVERT_TO_GCC_LIST OUTPUT_VARIABLE) + FOREACH(ITEM ${ARGN}) + LIST(APPEND ITEMS ${ITEM}) + ENDFOREACH(ITEM) + STRING(REPLACE ";" ":" OUTPUT "${ITEMS}") + SET("${OUTPUT_VARIABLE}" "${OUTPUT}" PARENT_SCOPE) +ENDFUNCTION(WRT_CONVERT_TO_GCC_LIST) diff --git a/tests/common/include/glib_interface.h b/tests/common/include/glib_interface.h new file mode 100644 index 0000000..5629f99 --- /dev/null +++ b/tests/common/include/glib_interface.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file glib_interface.h + * @author Iwanek Tomasz (t.iwanek@samsung.com) + * @version 1.0 + * @brief This file is the definitions of loop controlling utilities + */ + +#ifndef GLIB_INTERFACE_H +#define GLIB_INTERFACE_H + +//this header wraps glib headers which generates warnings + +#pragma GCC system_header +#include +#include + +#endif // GLIB_INTERFACE_H diff --git a/tests/common/include/loop_control.h b/tests/common/include/loop_control.h new file mode 100644 index 0000000..b58fb5c --- /dev/null +++ b/tests/common/include/loop_control.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file loop_control.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief This file is the definitions of loop controlling utilities + */ + +#ifndef LOOP_CONTROL_H_ +#define LOOP_CONTROL_H_ + +namespace LoopControl { +void init_loop(int argc, char *argv[]); +void wait_for_wrt_init(); +void finish_wait_for_wrt_init(); +void quit_loop(); + +void wrt_start_loop(); +void wrt_end_loop(); + +void *abstract_window(); +} + +#endif /* LOOP_CONTROL_H_ */ diff --git a/tests/common/src/loop_control.cpp b/tests/common/src/loop_control.cpp new file mode 100644 index 0000000..5c690c2 --- /dev/null +++ b/tests/common/src/loop_control.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file loop_control.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief This is implementation of EFL version of loop control + */ + +#include +#include +#include + +#include + +namespace LoopControl { +void init_loop(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + g_type_init(); + g_thread_init(NULL); + + LogDebug("Starting"); + elm_init(argc, argv); +} + +void wait_for_wrt_init() +{ + ecore_main_loop_begin(); +} + +void finish_wait_for_wrt_init() +{ + ecore_main_loop_quit(); +} + +void quit_loop() +{ + elm_shutdown(); +} + +void wrt_start_loop() +{ + ecore_main_loop_begin(); +} + +void wrt_end_loop() +{ + ecore_main_loop_quit(); +} + +void *abstract_window() +{ + return elm_win_add(NULL, "hello", ELM_WIN_BASIC); +} +} //end of LoopControl namespace diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt new file mode 100644 index 0000000..44d2321 --- /dev/null +++ b/tests/core/CMakeLists.txt @@ -0,0 +1,66 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) +# @version 1.0 +# @brief +# + +# +# Test files +# +# Define all DPL tests sources. +# Runner is responsible for runnint it all and +# generating proper output files +# + +SET(TARGET_NAME "wrt-commons-tests-core") + +# Set DPL tests sources +SET(DPL_TESTS_CORE_SOURCES + ${TESTS_DIR}/core/main.cpp + ${TESTS_DIR}/core/test_address.cpp + ${TESTS_DIR}/core/test_bind.cpp + ${TESTS_DIR}/core/test_binary_queue.cpp + ${TESTS_DIR}/core/test_foreach.cpp + ${TESTS_DIR}/core/test_log_unhandled_exception.cpp + ${TESTS_DIR}/core/test_once.cpp + ${TESTS_DIR}/core/test_serialization.cpp + ${TESTS_DIR}/core/test_scoped_array.cpp + ${TESTS_DIR}/core/test_scoped_close.cpp + ${TESTS_DIR}/core/test_scoped_dir.cpp + ${TESTS_DIR}/core/test_scoped_fclose.cpp + ${TESTS_DIR}/core/test_scoped_free.cpp + ${TESTS_DIR}/core/test_scoped_ptr.cpp + ${TESTS_DIR}/core/test_semaphore.cpp + ${TESTS_DIR}/core/test_shared_ptr.cpp + ${TESTS_DIR}/core/test_static_block.cpp + ${TESTS_DIR}/core/test_string.cpp + ${TESTS_DIR}/core/test_thread.cpp + ${TESTS_DIR}/core/test_type_list.cpp + ${TESTS_DIR}/core/test_zip_input.cpp + ${TESTS_DIR}/core/test_scope_guard.cpp + ${TESTS_DIR}/core/test_waitable_handle_watch.cpp + ${TESTS_DIR}/core/test_single_instance.cpp +) + +WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_NAME} ${TARGET_DPL_EFL}) +WRT_TEST_BUILD(${TARGET_NAME} ${DPL_TESTS_CORE_SOURCES}) +WRT_TEST_INSTALL(${TARGET_NAME}) + +INSTALL(FILES + ${TESTS_DIR}/core/data/sample.zip + DESTINATION /opt/share/wrt/wrt-commons/tests/core + ) diff --git a/tests/core/DESCRIPTION b/tests/core/DESCRIPTION new file mode 100644 index 0000000..48e5394 --- /dev/null +++ b/tests/core/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +Test code diff --git a/tests/core/data/sample.zip b/tests/core/data/sample.zip new file mode 100644 index 0000000..02417d8 Binary files /dev/null and b/tests/core/data/sample.zip differ diff --git a/tests/core/main.cpp b/tests/core/main.cpp new file mode 100644 index 0000000..42ffe3a --- /dev/null +++ b/tests/core/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main + */ +#include + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} + diff --git a/tests/core/test_address.cpp b/tests/core/test_address.cpp new file mode 100644 index 0000000..d887ca0 --- /dev/null +++ b/tests/core/test_address.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_address.cpp + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test address + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: Address_InitialEmpty +Description: tests empty constructor of DPL::Address +Expected: string version of empy address equals ":0" +*/ +RUNNER_TEST(Address_InitialEmpty) +{ + DPL::Address address; + RUNNER_ASSERT(address.ToString() == ":0"); +} + +/* +Name: Address_InitialAddress +Description: tests constructor of DPL::Address with name only +Expected: string version of address equals given name and appended ":0" +*/ +RUNNER_TEST(Address_InitialAddress) +{ + DPL::Address address("www.sample.com"); + RUNNER_ASSERT(address.ToString() == "www.sample.com:0"); +} + +/* +Name: Address_InitialAddress +Description: tests constructor of DPL::Address with name and port +Expected: string version of address should look lik "adress name:port" +*/ +RUNNER_TEST(Address_InitialAddressPort) +{ + DPL::Address address("www.somewhere.com", 8080); + RUNNER_ASSERT(address.ToString() == "www.somewhere.com:8080"); +} + +/* +Name: Address_InitialAddress +Description: tests getter of address +Expected: address name and port should matches those passed in constructor +*/ +RUNNER_TEST(Address_Getters) +{ + DPL::Address address("www.somewhere.com", 8080); + RUNNER_ASSERT(address.GetAddress() == "www.somewhere.com"); + RUNNER_ASSERT(address.GetPort() == 8080); +} diff --git a/tests/core/test_binary_queue.cpp b/tests/core/test_binary_queue.cpp new file mode 100644 index 0000000..cd8931d --- /dev/null +++ b/tests/core/test_binary_queue.cpp @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_binary_queue.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test binary queue + */ +#include +#include +RUNNER_TEST_GROUP_INIT(DPL) + +inline std::string BinaryQueueToString(const DPL::BinaryQueue &queue) +{ + char *buffer = new char[queue.Size()]; + queue.Flatten(buffer, queue.Size()); + std::string result = std::string(buffer, buffer + queue.Size()); + delete[] buffer; + return result; +} + +/* +Name: BinaryQueue_InitialEmpty +Description: tests emptiness of new constructed queue +Expected: new queue should be empty +*/ +RUNNER_TEST(BinaryQueue_InitialEmpty) +{ + DPL::BinaryQueue queue; + RUNNER_ASSERT(queue.Empty() == true); +} + +/* +Name: BinaryQueue_InitialSize +Description: tests emptiness of new constructed queue +Expected: new queue size should be equal 0 +*/ +RUNNER_TEST(BinaryQueue_InitialSize) +{ + DPL::BinaryQueue queue; + RUNNER_ASSERT(queue.Size() == 0); +} + +/* +Name: BinaryQueue_InitialCopy +Description: tests emptiness of new copy-constructed empty queue +Expected: queue constructed on base on empty queue should be empty +*/ +RUNNER_TEST(BinaryQueue_InitialCopy) +{ + DPL::BinaryQueue queue; + DPL::BinaryQueue copy = queue; + + RUNNER_ASSERT(copy.Size() == 0); +} + +/* +Name: BinaryQueue_InitialConsumeZero +Description: tests consume method accepts 0 bytes +Expected: it should be avaliable to discard 0 bytes from empty queue +*/ +RUNNER_TEST(BinaryQueue_InitialConsumeZero) +{ + DPL::BinaryQueue queue; + queue.Consume(0); +} + +/* +Name: BinaryQueue_InitialFlattenConsumeZero +Description: tests returning data from queue and discarding +Expected: it should be able to call flattenconsume with empty buffer if 0 bytes are read +*/ +RUNNER_TEST(BinaryQueue_InitialFlattenConsumeZero) +{ + DPL::BinaryQueue queue; + queue.FlattenConsume(NULL, 0); +} + +/* +Name: BinaryQueue_InitialFlattenZero +Description: tests returning data from queue +Expected: it should be able to call flatten with empty buffer if 0 bytes are read +*/ +RUNNER_TEST(BinaryQueue_InitialFlattenZero) +{ + DPL::BinaryQueue queue; + queue.Flatten(NULL, 0); +} + +/* +Name: BinaryQueue_InitialConsumeOne +Description: tests discarding more bytes than it is avaliable +Expected: exception throw +*/ +RUNNER_TEST(BinaryQueue_InitialConsumeOne) +{ + DPL::BinaryQueue queue; + + Try + { + queue.Consume(1); + } + Catch(DPL::BinaryQueue::Exception::OutOfData) + { + return; + } + + RUNNER_FAIL; +} + +/* +Name: BinaryQueue_InitialFlattenConsumeOne +Description: tests reading and discarding more bytes than it is avaliable +Expected: exception throw +*/ +RUNNER_TEST(BinaryQueue_InitialFlattenConsumeOne) +{ + DPL::BinaryQueue queue; + + Try + { + char data; + queue.FlattenConsume(&data, 1); + } + Catch(DPL::BinaryQueue::Exception::OutOfData) + { + return; + } + + RUNNER_FAIL; +} + +/* +Name: BinaryQueue_InitialFlattenOne +Description: tests reading more bytes than it is avaliable +Expected: exception throw +*/ +RUNNER_TEST(BinaryQueue_InitialFlattenOne) +{ + DPL::BinaryQueue queue; + + Try + { + char data; + queue.Flatten(&data, 1); + } + Catch(DPL::BinaryQueue::Exception::OutOfData) + { + return; + } + + RUNNER_FAIL; +} + +/* +Name: BinaryQueue_ZeroCopyFrom +Description: tests coping content of empty queue to another (AppendCopyFrom) +Expected: source queue should be empty +*/ +RUNNER_TEST(BinaryQueue_ZeroCopyFrom) +{ + DPL::BinaryQueue queue; + DPL::BinaryQueue copy; + + copy.AppendCopyFrom(queue); + RUNNER_ASSERT(queue.Empty()); +} + +/* +Name: BinaryQueue_ZeroMoveFrom +Description: tests moving content of empty queue to another +Expected: source queue should be empty +*/ +RUNNER_TEST(BinaryQueue_ZeroMoveFrom) +{ + DPL::BinaryQueue queue; + DPL::BinaryQueue copy; + + copy.AppendMoveFrom(queue); + RUNNER_ASSERT(queue.Empty()); +} + +/* +Name: BinaryQueue_ZeroCopyTo +Description: tests moving content of empty queue to another (AppendCopyTo) +Expected: source queue should be empty +*/ +RUNNER_TEST(BinaryQueue_ZeroCopyTo) +{ + DPL::BinaryQueue queue; + DPL::BinaryQueue copy; + + queue.AppendCopyTo(copy); + RUNNER_ASSERT(queue.Empty()); +} + +/* +Name: BinaryQueue_InsertSingleCharacters +Description: tests inserting single bytes to queue +Expected: stringified content and size shoudl match expected +*/ +RUNNER_TEST(BinaryQueue_InsertSingleCharacters) +{ + DPL::BinaryQueue queue; + + queue.AppendCopy("a", 1); + queue.AppendCopy("b", 1); + queue.AppendCopy("c", 1); + queue.AppendCopy("d", 1); + + RUNNER_ASSERT(queue.Size() == 4); + RUNNER_ASSERT(BinaryQueueToString(queue) == "abcd"); +} + +/* +Name: BinaryQueue_Consume +Description: tests comsuming portions of 1 or 2 bytes +Expected: stringified content and size should match expected + Bytes should be pope from begin. +*/ +RUNNER_TEST(BinaryQueue_Consume) +{ + DPL::BinaryQueue queue; + + queue.AppendCopy("abcd", 4); + queue.AppendCopy("ef", 2); + + RUNNER_ASSERT(queue.Size() == 6); + + queue.Consume(1); + RUNNER_ASSERT(queue.Size() == 5); + RUNNER_ASSERT(BinaryQueueToString(queue) == "bcdef"); + + queue.Consume(2); + RUNNER_ASSERT(queue.Size() == 3); + RUNNER_ASSERT(BinaryQueueToString(queue) == "def"); + + queue.Consume(1); + RUNNER_ASSERT(queue.Size() == 2); + RUNNER_ASSERT(BinaryQueueToString(queue) == "ef"); + + queue.Consume(2); + RUNNER_ASSERT(queue.Size() == 0); + RUNNER_ASSERT(BinaryQueueToString(queue) == ""); +} + +/* +Name: BinaryQueue_Flatten +Description: tests comsuming portions of 1 and more bytes +Expected: stringified content and size should match expected +*/ +RUNNER_TEST(BinaryQueue_Flatten) +{ + DPL::BinaryQueue queue; + + queue.AppendCopy("abcd", 4); + queue.AppendCopy("ef", 2); + queue.AppendCopy("g", 1); + + RUNNER_ASSERT(queue.Size() == 7); + + RUNNER_ASSERT(BinaryQueueToString(queue) == "abcdefg"); +} + +/* +Name: BinaryQueue_FlattenConsume +Description: tests comsuming portions of 1 and more bytes +Expected: stringified content and size should match expected + reading and discarding bytes should affect queue's size and content +*/ +RUNNER_TEST(BinaryQueue_FlattenConsume) +{ + DPL::BinaryQueue queue; + + queue.AppendCopy("abcd", 4); + queue.AppendCopy("ef", 2); + + RUNNER_ASSERT(queue.Size() == 6); + + char buffer[7] = { '\0' }; + queue.FlattenConsume(buffer, 3); + + RUNNER_ASSERT(queue.Size() == 3); + RUNNER_ASSERT(BinaryQueueToString(queue) == "def"); +} + +/* +Name: BinaryQueue_AppendCopyFrom +Description: tests creating copy of not empty queue (use of: AppendCopyFrom) +Expected: stringified content and size should match expected + from original queue and it's copy +*/ +RUNNER_TEST(BinaryQueue_AppendCopyFrom) +{ + DPL::BinaryQueue queue; + DPL::BinaryQueue copy; + + queue.AppendCopy("abcd", 4); + queue.AppendCopy("ef", 2); + + copy.AppendCopyFrom(queue); + + RUNNER_ASSERT(queue.Size() == 6); + RUNNER_ASSERT(copy.Size() == 6); + RUNNER_ASSERT(BinaryQueueToString(queue) == "abcdef"); + RUNNER_ASSERT(BinaryQueueToString(copy) == "abcdef"); +} + +/* +Name: BinaryQueue_AppendCopyTo +Description: tests creating copy of not empty queue (use of: AppendCopyTo) +Expected: stringified content and size should match expected + from original queue and it's copy +*/ +RUNNER_TEST(BinaryQueue_AppendCopyTo) +{ + DPL::BinaryQueue queue; + DPL::BinaryQueue copy; + + queue.AppendCopy("abcd", 4); + queue.AppendCopy("ef", 2); + + queue.AppendCopyTo(copy); + + RUNNER_ASSERT(queue.Size() == 6); + RUNNER_ASSERT(copy.Size() == 6); + RUNNER_ASSERT(BinaryQueueToString(queue) == "abcdef"); + RUNNER_ASSERT(BinaryQueueToString(copy) == "abcdef"); +} + +/* +Name: BinaryQueue_AppendMoveFrom +Description: tests moving content of not empty queue (use of: AppendMoveFrom) +Expected: stringified content and size should match expected + for new queue. Old queue should be empty after operation +*/ +RUNNER_TEST(BinaryQueue_AppendMoveFrom) +{ + DPL::BinaryQueue queue; + DPL::BinaryQueue copy; + + queue.AppendCopy("abcd", 4); + queue.AppendCopy("ef", 2); + + copy.AppendMoveFrom(queue); + + RUNNER_ASSERT(queue.Size() == 0); + RUNNER_ASSERT(copy.Size() == 6); + RUNNER_ASSERT(BinaryQueueToString(queue) == ""); + RUNNER_ASSERT(BinaryQueueToString(copy) == "abcdef"); +} + +/* +Name: BinaryQueue_AppendMoveFrom +Description: tests moving content of not empty queue (use of: AppendMoveTo) +Expected: stringified content and size should match expected + for new queue. Old queue should be empty after operation +*/ +RUNNER_TEST(BinaryQueue_AppendMoveTo) +{ + DPL::BinaryQueue queue; + DPL::BinaryQueue copy; + + queue.AppendCopy("abcd", 4); + queue.AppendCopy("ef", 2); + + queue.AppendMoveTo(copy); + + RUNNER_ASSERT(queue.Size() == 0); + RUNNER_ASSERT(copy.Size() == 6); + RUNNER_ASSERT(BinaryQueueToString(queue) == ""); + RUNNER_ASSERT(BinaryQueueToString(copy) == "abcdef"); +} + +class Visitor : + public DPL::BinaryQueue::BucketVisitor +{ + private: + int m_index; + + public: + Visitor() : + m_index(0) + {} + + virtual void OnVisitBucket(const void *buffer, size_t bufferSize) + { + const char *str = static_cast(buffer); + + if (m_index == 0) { + RUNNER_ASSERT(bufferSize == 4); + RUNNER_ASSERT(str[0] == 'a'); + RUNNER_ASSERT(str[1] == 'b'); + RUNNER_ASSERT(str[2] == 'c'); + RUNNER_ASSERT(str[3] == 'd'); + } else if (m_index == 1) { + RUNNER_ASSERT(bufferSize == 2); + RUNNER_ASSERT(str[0] == 'e'); + RUNNER_ASSERT(str[1] == 'f'); + } else { + RUNNER_FAIL; + } + + ++m_index; + } +}; + +/* +Name: BinaryQueue_Visitor +Description: tests byte by byte content of queue by use of visitor +Expected: stringified content and size should match expected + Each byte should be at right position +*/ +RUNNER_TEST(BinaryQueue_Visitor) +{ + DPL::BinaryQueue queue; + + queue.AppendCopy("abcd", 4); + queue.AppendCopy("ef", 2); + + Visitor visitor; + queue.VisitBuckets(&visitor); +} + +RUNNER_TEST(BinaryQueue_AbstracInputRead) +{ + DPL::BinaryQueue queue; + + queue.AppendCopy("abcd", 4); + + queue.Read(0); + + RUNNER_ASSERT(BinaryQueueToString(*queue.Read(1).get()) == "a"); + RUNNER_ASSERT(BinaryQueueToString(*queue.Read(2).get()) == "bc"); + RUNNER_ASSERT(BinaryQueueToString(*queue.Read(1).get()) == "d"); + + RUNNER_ASSERT(queue.Size() == 0); +} + +/* +Name: BinaryQueue_AbstracOutputWrite +Description: tests appending one queue to another +Expected: written bytes shoudl affect content and size of queue +*/ +RUNNER_TEST(BinaryQueue_AbstracOutputWrite) +{ + DPL::BinaryQueue queue; + queue.AppendCopy("abcd", 4); + + DPL::BinaryQueue stream; + + stream.Write(queue, 4); + + RUNNER_ASSERT(BinaryQueueToString(*queue.Read(4).get()) == "abcd"); +} diff --git a/tests/core/test_bind.cpp b/tests/core/test_bind.cpp new file mode 100644 index 0000000..f71d418 --- /dev/null +++ b/tests/core/test_bind.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_bind.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test bind + */ +#include + +#include +#include + +namespace { +const int MAGIC_INT = 42; +const double MAGIC_DOUBLE = 42.42; + +struct BindTestBase { + BindTestBase() : called{false} {} + + bool called; +}; + +struct BindNoArguments : BindTestBase { + void foo() { called = true; } +}; + +struct BindWithArguments : BindTestBase { + void foo(int, double) { called = true; } +}; + +struct BindWithArgumentsAndResult : BindTestBase { + int foo(int, double) { called = true; return MAGIC_INT; } +}; +} + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: Bind_NoArguments +Description: tests binding method without arguments +Expected: bound method called +*/ +RUNNER_TEST(Bind_NoArguments) +{ + BindNoArguments test; + + std::function delegate = DPL::Bind(&BindNoArguments::foo, &test); + delegate(); + + RUNNER_ASSERT(test.called); +} + +/* +Name: Bind_WithArguments +Description: tests binding method with arguments +Expected: bound method called +*/ +RUNNER_TEST(Bind_WithArguments) +{ + BindWithArguments test; + + std::function delegate = + DPL::Bind(&BindWithArguments::foo, &test); + delegate(MAGIC_INT, MAGIC_DOUBLE); + + RUNNER_ASSERT(test.called); +} + +/* +Name: Bind_WithArgumentsAndResult +Description: tests binding method with arguments and result +Expected: bound method called +*/ +RUNNER_TEST(Bind_WithArgumentsAndResult) +{ + BindWithArgumentsAndResult test; + + std::function delegate = + DPL::Bind(&BindWithArgumentsAndResult::foo, &test); + int result = delegate(MAGIC_INT, MAGIC_DOUBLE); + + RUNNER_ASSERT(test.called); + RUNNER_ASSERT(MAGIC_INT == result); +} diff --git a/tests/core/test_foreach.cpp b/tests/core/test_foreach.cpp new file mode 100644 index 0000000..08d66df --- /dev/null +++ b/tests/core/test_foreach.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_foreach.cpp + * @author Bartosz Janiak (b.janiak@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of foreach tests. + */ + +#include +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +static const size_t testContainerSize = 1024; + +template +void VerifyForeach(Container& container) +{ + size_t i = 0; + FOREACH(it, container) + { + RUNNER_ASSERT(*it == i); + i++; + } + RUNNER_ASSERT(i == container.size()); +} + +#define VERIFY_FOREACH(container) \ + { \ + size_t i = 0; \ + FOREACH(it, container) \ + { \ + RUNNER_ASSERT(*it == i); \ + i++; \ + } \ + } + +static size_t numberOfCallsToTemporaryList = 0; +std::list temporaryList(); +std::list temporaryList() +{ + ++numberOfCallsToTemporaryList; + std::list list; + for (size_t i = 0; i < testContainerSize; i++) { + list.push_back(i); + } + return list; +} + +static size_t numberOfCallsToTemporaryVector = 0; +std::vector temporaryVector(); +std::vector temporaryVector() +{ + ++numberOfCallsToTemporaryVector; + std::vector vector; + for (size_t i = 0; i < testContainerSize; i++) { + vector.push_back(i); + } + return vector; +} + +static size_t numberOfCallsToTemporarySet = 0; +std::set temporarySet(); +std::set temporarySet() +{ + ++numberOfCallsToTemporarySet; + std::set set; + for (size_t i = 0; i < testContainerSize; i++) { + set.insert(i); + } + return set; +} + +/* +Name: Foreach_std_containers +Description: tests iterating contianers set, list, vector using foreach +Expected: value supplied by foreach matches sequence of integers +*/ +RUNNER_TEST(Foreach_std_containers) +{ + std::vector vector; + std::list list; + std::set set; + + for (size_t i = 0; i < testContainerSize; i++) { + vector.push_back(i); + list.push_back(i); + set.insert(i); + } + + VerifyForeach(vector); + VerifyForeach(list); + VerifyForeach(set); + + VERIFY_FOREACH(temporaryList()); + VERIFY_FOREACH(temporaryVector()); + VERIFY_FOREACH(temporarySet()); + + RUNNER_ASSERT(numberOfCallsToTemporaryList == 1); + RUNNER_ASSERT(numberOfCallsToTemporaryVector == 1); + RUNNER_ASSERT(numberOfCallsToTemporarySet == 1); +} diff --git a/tests/core/test_log_unhandled_exception.cpp b/tests/core/test_log_unhandled_exception.cpp new file mode 100644 index 0000000..3299357 --- /dev/null +++ b/tests/core/test_log_unhandled_exception.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_log_unhandled_exception.cpp + * @author Pawel Sikorski (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief + */ +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +class MyException +{}; + +class MyDPLException +{ + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, MyException) +}; + +class MySTDException : + public std::exception +{ + public: + virtual const char* what() const throw() + { + return "my std exception occurred"; + } +}; + +/* +Name: Log_Unknown_Exception +Description: tests exceptions catching macros +Expected: unknown exception should be catched + +TODO: workaround abort call +*/ +RUNNER_TEST(Log_Unknown_Exception) +{ + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + // throw MyException(); + } + UNHANDLED_EXCEPTION_HANDLER_END + RUNNER_ASSERT(true); +} + +/* +Name: Log_DPL_Exception +Description: tests exceptions catching macros +Expected: DPL exception should be catched + +TODO: workaround abort call +*/ +RUNNER_TEST(Log_DPL_Exception) +{ + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + // Throw(MyDPLException::MyException); + } + UNHANDLED_EXCEPTION_HANDLER_END + RUNNER_ASSERT(true); +} + +/* +Name: Log_STD_Exception +Description: tests exceptions catching macros +Expected: STD exception should be catched + +TODO: workaround abort call +*/ +RUNNER_TEST(Log_STD_Exception) +{ + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + // throw MySTDException(); + } + UNHANDLED_EXCEPTION_HANDLER_END + RUNNER_ASSERT(true); +} diff --git a/tests/core/test_once.cpp b/tests/core/test_once.cpp new file mode 100644 index 0000000..5ba7ecb --- /dev/null +++ b/tests/core/test_once.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_once.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of once tests + */ +#include + +#include +#include +#include +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +namespace // anonymous +{ +gint g_counter; + +void Delegate() +{ + ++g_counter; +} +} // namespace anonymous + +RUNNER_TEST(Once_DoubleCall) +{ + g_counter = 0; + + DPL::Once once; + + once.Call(&Delegate); + once.Call(&Delegate); + + RUNNER_ASSERT_MSG(g_counter == 1, "Counter value is: " << g_counter); +} + +class MyThread : + public DPL::Thread +{ + protected: + virtual int ThreadEntry() + { + DPL::WaitForSingleHandle(m_event->GetHandle()); + m_once->Call(std::bind(&MyThread::Call, this)); + return 0; + } + + void Call() + { + ++*m_atom; + } + + public: + MyThread(DPL::WaitableEvent *event, DPL::Once *once, DPL::Atomic *atom) : + m_event(event), m_once(once), m_atom(atom) + {} + + private: + DPL::WaitableEvent *m_event; + DPL::Once *m_once; + DPL::Atomic *m_atom; +}; + +/* +Name: Once_MultiThreadCall +Description: tests once call wrapper for use by multiple threads +Expected: function should be called just once from one of running threads +*/ +RUNNER_TEST(Once_MultiThreadCall) +{ + const size_t NUM_THREADS = 20; + typedef std::shared_ptr ThreadPtr; + + ThreadPtr threads[NUM_THREADS]; + DPL::WaitableEvent event; + DPL::Once once; + DPL::Atomic atom; + + for (size_t i = 0; i < NUM_THREADS; ++i) { + (threads[i] = ThreadPtr(new MyThread(&event, &once, &atom)))->Run(); + } + + event.Signal(); + + for (size_t i = 0; i < NUM_THREADS; ++i) { + threads[i]->Quit(); + } + + RUNNER_ASSERT_MSG(atom == 1, "Atom value is: " << atom); +} diff --git a/tests/core/test_scope_guard.cpp b/tests/core/test_scope_guard.cpp new file mode 100644 index 0000000..7c09645 --- /dev/null +++ b/tests/core/test_scope_guard.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_scope_guard.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scope guard + */ +#include +#include + +namespace { +bool g_guardCalled = false; + +void regularFunction() +{ + g_guardCalled = true; +} + +struct Functor +{ + explicit Functor(bool& guardCalled) + : m_guardCalled(guardCalled) + {} + + void operator()() + { + m_guardCalled = true; + } + + bool& m_guardCalled; +}; +} + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: ScopeGuard_MakeScopeGuard_RegularFunction +Description: tests scope guard, created explicitly, with regular function +Expected: guard should be called +*/ +RUNNER_TEST(ScopeGuard_MakeScopeGuard_RegularFunction) +{ + g_guardCalled = false; + { + auto guard = DPL::MakeScopeGuard(regularFunction); + } + RUNNER_ASSERT(g_guardCalled); +} + +/* +Name: ScopeGuard_MakeScopeGuard_Functor +Description: tests scope guard, created explicitly, with a functor +Expected: guard should be called +*/ +RUNNER_TEST(ScopeGuard_MakeScopeGuard_Functor) +{ + g_guardCalled = false; + { + auto guard = DPL::MakeScopeGuard(Functor(g_guardCalled)); + } + RUNNER_ASSERT(g_guardCalled); +} + +/* +Name: ScopeGuard_MakeScopeGuard_Lambda +Description: tests scope guard, created explicitly, with a lambda +Expected: guard should be called +*/ +RUNNER_TEST(ScopeGuard_MakeScopeGuard_Lambda) +{ + g_guardCalled = false; + { + auto guard = DPL::MakeScopeGuard( + [&g_guardCalled](){ g_guardCalled = true; }); + } + RUNNER_ASSERT(g_guardCalled); +} + +/* +Name: ScopeGuard_Macro +Description: tests scope guard, created implicitly, with a lambda +Expected: guard should be called +*/ +RUNNER_TEST(ScopeGuard_Macro) +{ + g_guardCalled = false; + { + DPL_SCOPE_EXIT(&g_guardCalled) + { + g_guardCalled = true; + }; + } + RUNNER_ASSERT(g_guardCalled); +} + +/* +Name: ScopeGuard_Release +Description: tests scope guard releasing API +Expected: guard should not be called +*/ +RUNNER_TEST(ScopeGuard_Release) +{ + g_guardCalled = false; + { + auto guard = DPL::MakeScopeGuard( + [&g_guardCalled](){ g_guardCalled = true; }); + guard.Release(); + } + RUNNER_ASSERT(!g_guardCalled); +} diff --git a/tests/core/test_scoped_array.cpp b/tests/core/test_scoped_array.cpp new file mode 100644 index 0000000..f2a3b4b --- /dev/null +++ b/tests/core/test_scoped_array.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_scoped_array.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scoped array + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: ScopedArray_Zero +Description: tests emptiness of empty scoped array +Expected: array should be empty +*/ +RUNNER_TEST(ScopedArray_Zero) +{ + DPL::ScopedArray array; + + RUNNER_ASSERT(!array); + RUNNER_ASSERT(!!!array); +} + +/* +Name: ScopedArray_NonZero +Description: tests emptiness of not empty scoped array +Expected: array should be not empty +*/ +RUNNER_TEST(ScopedArray_NonZero) +{ + DPL::ScopedArray array(new char[7]); + + RUNNER_ASSERT(array); + RUNNER_ASSERT(!!array); +} + +/* +Name: ScopedArray_Reset +Description: tests reseting content of array +Expected: array should be empty after reset +*/ +RUNNER_TEST(ScopedArray_Reset) +{ + DPL::ScopedArray array(new char[7]); + array.Reset(); + + RUNNER_ASSERT(!array); + + array.Reset(new char); + RUNNER_ASSERT(array); +} + +/* +Name: ScopedArray_ArrayOperator +Description: tests accessing elements of array +Expected: returned values should be equal to those which were set +*/ +RUNNER_TEST(ScopedArray_ArrayOperator) +{ + DPL::ScopedArray array(new char[7]); + + array[1] = array[2] = 3; + + RUNNER_ASSERT(array[1] == 3); + RUNNER_ASSERT(array[2] == 3); +} diff --git a/tests/core/test_scoped_close.cpp b/tests/core/test_scoped_close.cpp new file mode 100644 index 0000000..3549fed --- /dev/null +++ b/tests/core/test_scoped_close.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_scoped_close.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scoped close + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +// DUNNO diff --git a/tests/core/test_scoped_dir.cpp b/tests/core/test_scoped_dir.cpp new file mode 100644 index 0000000..8cf0c3c --- /dev/null +++ b/tests/core/test_scoped_dir.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_scoped_dir.cpp + * @author Iwanek Tomasz (t.iwanek@smasung.com) + * @version 1.0 + * @brief Scoped directory test + */ +#include +#include + +#include +#include +#include + +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: ScopedDir_Basic +Description: tests if scoped directory is working +Expected: directory created and removed +*/ +RUNNER_TEST(ScopedDir_Basic) +{ + const char * path = "/tmp/wrttest123456"; + if(access(path, F_OK) == 0) + { + RUNNER_ASSERT_MSG(!remove(path), "Cannot remove test directory"); + } + + { + DPL::ScopedDir dir(path, S_IRUSR | S_IWUSR); + std::ostringstream command; + command << "touch " << path << "/" << "file.txt"; + (void)system(command.str().c_str()); + RUNNER_ASSERT_MSG(access(path, R_OK) == 0, "Directory should be accessible"); + RUNNER_ASSERT_MSG(access(path, W_OK) == 0, "Directory should be writable"); + } + RUNNER_ASSERT_MSG(access(path, F_OK) != 0, "Directory should not exists"); +} diff --git a/tests/core/test_scoped_fclose.cpp b/tests/core/test_scoped_fclose.cpp new file mode 100644 index 0000000..7667a9e --- /dev/null +++ b/tests/core/test_scoped_fclose.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * @file test_scoped_fclose.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scoped fclose + */ + +#include +#include + +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +namespace { +FILE* MakeTmp() +{ + FILE* result = NULL; + do { + result = tmpfile(); + } while (NULL != result && EINTR == errno); + return result; +} +} //anonymous namespace + +/* +Name: ScopedFClose_Zero +Description: tests if operator ! works correct for closed file +Expected: file should be closed +*/ +RUNNER_TEST(ScopedFClose_Zero) +{ + DPL::ScopedFClose file; + + RUNNER_ASSERT(!file); + RUNNER_ASSERT(!!!file); +} + +/* +Name: ScopedArray_NonZero +Description: tests if operator ! works correct for open file +Expected: file should be open +*/ +RUNNER_TEST(ScopedFClose_NonZero) +{ + DPL::ScopedFClose file(MakeTmp()); + + RUNNER_ASSERT(file); + RUNNER_ASSERT(!!file); +} + +/* +Name: ScopedFClose_Reset +Description: tests reseting of scoped file +Expected: file should be closed after reset +*/ +RUNNER_TEST(ScopedFClose_Reset) +{ + DPL::ScopedFClose file(MakeTmp()); + file.Reset(); + + RUNNER_ASSERT(!file); + + file.Reset(MakeTmp()); + RUNNER_ASSERT(file); +} + diff --git a/tests/core/test_scoped_free.cpp b/tests/core/test_scoped_free.cpp new file mode 100644 index 0000000..25bd6d6 --- /dev/null +++ b/tests/core/test_scoped_free.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_scoped_free.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scoped free + */ +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: ScopedFree_Zero +Description: Checks emptiness of not set scoped free +Expected: resource should be freed +*/ +RUNNER_TEST(ScopedFree_Zero) +{ + DPL::ScopedFree free; + + RUNNER_ASSERT(!free); + RUNNER_ASSERT(!!!free); +} + +/* +Name: ScopedFree_NonZero +Description: Checks emptiness of set scoped free +Expected: resource should not be reported as freed +*/ +RUNNER_TEST(ScopedFree_NonZero) +{ + DPL::ScopedFree free(malloc(7)); + + RUNNER_ASSERT(free); + RUNNER_ASSERT(!!free); +} + +/* +Name: ScopedFree_Reset +Description: Checks reseting scoped free +Expected: resource should be freed after reset +*/ +RUNNER_TEST(ScopedFree_Reset) +{ + DPL::ScopedFree free(malloc(7)); + free.Reset(); + + RUNNER_ASSERT(!free); + + free.Reset(malloc(8)); + RUNNER_ASSERT(free); +} diff --git a/tests/core/test_scoped_ptr.cpp b/tests/core/test_scoped_ptr.cpp new file mode 100644 index 0000000..af17bac --- /dev/null +++ b/tests/core/test_scoped_ptr.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_scoped_ptr.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test scoped ptr + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: ScopedPtr_Zero +Description: Checks if operator! works +Expected: resource should be not set +*/ +RUNNER_TEST(ScopedPtr_Zero) +{ + DPL::ScopedPtr ptr; + + RUNNER_ASSERT(!ptr); + RUNNER_ASSERT(!!!ptr); +} + +/* +Name: ScopedPtr_NonZero +Description: Checks if operator! works +Expected: resource should be set +*/ +RUNNER_TEST(ScopedPtr_NonZero) +{ + DPL::ScopedPtr ptr(new char(7)); + + RUNNER_ASSERT(ptr); + RUNNER_ASSERT(!!ptr); +} + +/* +Name: ScopedPtr_Reset +Description: Checks reseting scoped ptr +Expected: resource should be not set after reset +*/ +RUNNER_TEST(ScopedPtr_Reset) +{ + DPL::ScopedPtr ptr(new char(7)); + ptr.Reset(); + + RUNNER_ASSERT(!ptr); + + ptr.Reset(new char); + RUNNER_ASSERT(ptr); +} + +/* +Name: ScopedPtr_Operators +Description: Checks access operator +Expected: address of resource should be same as this, received from Get() method +*/ +RUNNER_TEST(ScopedPtr_Operators) +{ + DPL::ScopedPtr ptr(new char(7)); + + RUNNER_ASSERT(*ptr == *ptr.Get()); +} diff --git a/tests/core/test_semaphore.cpp b/tests/core/test_semaphore.cpp new file mode 100644 index 0000000..c93b365 --- /dev/null +++ b/tests/core/test_semaphore.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_semaphore.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of semaphore tests + */ +#include +#include +#include +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +class SemaphoreThread : + public DPL::Thread +{ + int m_delta; + int m_times; + int *m_value; + std::string m_semaphoreName; + + public: + SemaphoreThread(int delta, + int times, + int *value, + const std::string &semaphoreName) : + m_delta(delta), + m_times(times), + m_value(value), + m_semaphoreName(semaphoreName) + {} + + protected: + virtual int ThreadEntry() + { + DPL::Semaphore semaphore(m_semaphoreName); + + for (int i = 0; i < m_times; ++i) { + // Take scoped semaphore lock + DPL::Semaphore::ScopedLock lock(&semaphore); + *m_value += m_delta; + } + + return 0; + } +}; + +/* +Name: Semaphore_NamedIncrementDecrement +Description: Checks if semaphore are working +Expected: value should not change after all +*/ +RUNNER_TEST(Semaphore_NamedIncrementDecrement) +{ + std::string semaphoreName = + "dpl_test_semaphore_" + + DPL::lexical_cast(std::time(NULL)); + + int value = 0; + SemaphoreThread threadA(-1, 10000, &value, semaphoreName); + SemaphoreThread threadB(+1, 10000, &value, semaphoreName); + + threadA.Run(); + threadB.Run(); + + threadA.Quit(); + threadB.Quit(); + + RUNNER_ASSERT_MSG(value == 0, "Final value is: " << value); +} diff --git a/tests/core/test_serialization.cpp b/tests/core/test_serialization.cpp new file mode 100644 index 0000000..7bbf8de --- /dev/null +++ b/tests/core/test_serialization.cpp @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_address.cpp + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of serialization tests + */ + +#include +#include +#include +#include + +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +// test stream class +class BinaryStream : public DPL::IStream +{ + public: + virtual void Read(size_t num, void * bytes) + { + for (unsigned i = 0; i < num; ++i) { + ((unsigned char*)bytes)[i] = data[i + readPosition]; + } + readPosition += num; + } + virtual void Write(size_t num, const void * bytes) + { + for (unsigned i = 0; i < num; ++i) { + data.push_back(((unsigned char*)bytes)[i]); + } + } + BinaryStream() + { + readPosition = 0; + } + virtual ~BinaryStream(){} + + private: + std::vector data; + unsigned readPosition; +}; + +//test ISerializable class +class TestClass : public DPL::ISerializable +{ + public: + TestClass(int val, std::string str1, std::string str2) + { + a = val; + b = str1; + c.push_back(str1); + c.push_back(str2); + c.push_back(str1 + str2); + } + TestClass(DPL::IStream& stream) : + a(0) //TODO: consider the need (g.rynkowski) + { + DPL::Deserialization::Deserialize(stream, a); + DPL::Deserialization::Deserialize(stream, b); + DPL::Deserialization::Deserialize(stream, c); + } + virtual void Serialize(DPL::IStream& stream) const + { + DPL::Serialization::Serialize(stream, a); + DPL::Serialization::Serialize(stream, b); + DPL::Serialization::Serialize(stream, c); + } + virtual ~TestClass(){} + virtual bool operator==(const TestClass& other) + { + return (a == other.a && + b == other.b && + c.size() == other.c.size() && + c[0] == other.c[0] && + c[1] == other.c[1] && + c[2] == other.c[2]); + } + + private: + int a; + std::string b; + std::vector c; +}; + +/* +Name: Serialize_primitives +Description: Tests serialization of primitives types +Expected: serialized value after deserialization + should be equal to deserialied value +*/ +RUNNER_TEST(Serialize_primitives) +{ + int a = 1; + bool b = true; + unsigned c = 23; + BinaryStream stream; + DPL::Serialization::Serialize(stream, a); + DPL::Serialization::Serialize(stream, b); + DPL::Serialization::Serialize(stream, c); + int test_int; + DPL::Deserialization::Deserialize(stream, test_int); + RUNNER_ASSERT(test_int == a); + bool test_bool; + DPL::Deserialization::Deserialize(stream, test_bool); + RUNNER_ASSERT(test_bool == b); + unsigned test_unsigned; + DPL::Deserialization::Deserialize(stream, test_unsigned); + RUNNER_ASSERT(test_unsigned == c); +} + +/* +Name: Serialize_primitive_pointers +Description: Tests serialization of primitives pointer types +Expected: serialized value after deserialization + should be equal to deserialied value +*/ +RUNNER_TEST(Serialize_primitive_pointers) +{ + int a = 1; + bool b = true; + unsigned c = 23; + BinaryStream stream; + DPL::Serialization::Serialize(stream, &a); + DPL::Serialization::Serialize(stream, &b); + DPL::Serialization::Serialize(stream, &c); + int* test_int; + DPL::Deserialization::Deserialize(stream, test_int); + RUNNER_ASSERT(test_int != NULL && *test_int == a); + bool* test_bool; + DPL::Deserialization::Deserialize(stream, test_bool); + RUNNER_ASSERT(test_bool != NULL && *test_bool == b); + unsigned* test_unsigned; + DPL::Deserialization::Deserialize(stream, test_unsigned); + RUNNER_ASSERT(test_unsigned != NULL && *test_unsigned == c); + delete test_int; + delete test_bool; + delete test_unsigned; +} + +/* +Name: Serialize_strings +Description: Tests serialization of strings +Expected: serialized value after deserialization + should be equal to deserialied value +*/ +RUNNER_TEST(Serialize_strings) +{ + std::string str1 = "ALA MA KOTA"; + std::string str2 = "MULTILINE\nTEST"; + BinaryStream stream; + DPL::Serialization::Serialize(stream, str1); + DPL::Serialization::Serialize(stream, str2); + std::string test_str1; + DPL::Deserialization::Deserialize(stream, test_str1); + RUNNER_ASSERT(test_str1 == str1); + std::string test_str2; + DPL::Deserialization::Deserialize(stream, test_str2); + RUNNER_ASSERT(test_str2 == str2); +} + +/* +Name: Serialize_string_pointers +Description: Tests serialization of string pointers +Expected: serialized value after deserialization + should be equal to deserialied value +*/ +RUNNER_TEST(Serialize_string_pointers) +{ + std::string str1 = "ALA MA KOTA"; + std::string str2 = "MULTILINE\nTEST"; + BinaryStream stream; + DPL::Serialization::Serialize(stream, &str1); + DPL::Serialization::Serialize(stream, &str2); + std::string* test_str1; + DPL::Deserialization::Deserialize(stream, test_str1); + RUNNER_ASSERT(test_str1 != NULL && *test_str1 == str1); + std::string* test_str2; + DPL::Deserialization::Deserialize(stream, test_str2); + RUNNER_ASSERT(test_str2 != NULL && *test_str2 == str2); + delete test_str1; + delete test_str2; +} + +/* +Name: Serialize_containers +Description: Tests serialization of containers +Expected: serialized value after deserialization + should be equal to deserialied value +*/ +RUNNER_TEST(Serialize_containers) +{ + std::vector vec; + vec.push_back(134); + vec.push_back(265); + std::list list; + list.push_back(true); + list.push_back(false); + std::pair pair; + pair.first = -23; + pair.second = 1234; + std::map map; + map.insert(std::pair(45, "ALA MA CZARNEGO KOTA")); + map.insert(std::pair(-78, "...A MOZE\nMA\nWIELE LINIJEK")); + BinaryStream stream; + DPL::Serialization::Serialize(stream, vec); + DPL::Serialization::Serialize(stream, list); + DPL::Serialization::Serialize(stream, pair); + DPL::Serialization::Serialize(stream, map); + std::vector test_vec; + DPL::Deserialization::Deserialize(stream, test_vec); + RUNNER_ASSERT(test_vec.size() == vec.size() && + test_vec[0] == vec[0] && test_vec[1] == vec[1]); + std::list test_list; + DPL::Deserialization::Deserialize(stream, test_list); + RUNNER_ASSERT(test_list.size() == list.size() && + test_list.front() == list.front() && + test_list.back() == test_list.back()); + std::pair test_pair; + DPL::Deserialization::Deserialize(stream, test_pair); + RUNNER_ASSERT(test_pair.first == pair.first && + test_pair.second == pair.second); + std::map test_map; + DPL::Deserialization::Deserialize(stream, test_map); + RUNNER_ASSERT(test_map.size() == map.size() && + test_map.at(45) == map.at(45) && + test_map.at(-78) == map.at(-78)); +} + +/* +Name: Serialize_objects +Description: Tests serialization of DPL::ISerializable derived objects +Expected: serialized value after deserialization + should be equal to deserialied value +*/ +RUNNER_TEST(Serialize_objects) +{ + TestClass a(123, "ASDGHUADB\n\n5679b^^()*", "TEST_STRING"), + b(679, "HUSPIDNSAHDPA", "\nASDSADASD\naDSADASD8"); + BinaryStream stream; + DPL::Serialization::Serialize(stream, a); + DPL::Serialization::Serialize(stream, b); + TestClass test_a(0, "", ""), test_b(0, "", ""); + DPL::Deserialization::Deserialize(stream, test_a); + RUNNER_ASSERT(test_a == a); + DPL::Deserialization::Deserialize(stream, test_b); + RUNNER_ASSERT(test_b == b); +} + +/* +Name: Serialize_all +Description: Tests serialization of compound objects +Expected: serialized value after deserialization + should be equal to deserialied value +*/ +RUNNER_TEST(Serialize_all) +{ + std::map > map; + std::vector vec; + vec.push_back(new TestClass(123, "ASDGHUADB\n\n5679b^^()*", "TEST_STRING")); + vec.push_back(new TestClass(679, "HUSPIDNSAHDPA", "\nASDSADASD\naDSADASD8")); + map.insert(std::pair >("KEY1", vec)); + map.insert(std::pair >("KEY2", vec)); + BinaryStream stream; + + DPL::Serialization::Serialize(stream, map); + + std::map > test_map; + DPL::Deserialization::Deserialize(stream, test_map); + RUNNER_ASSERT(map.size() == test_map.size()); + std::vector test_vec1, test_vec2; + test_vec1 = map.at("KEY1"); + test_vec2 = test_map.at("KEY1"); + RUNNER_ASSERT(test_vec1.size() == test_vec2.size()); + unsigned i; + for (i = 0; i < test_vec1.size(); ++i) { + RUNNER_ASSERT((*test_vec1[i]) == (*test_vec2[i])); + } + test_vec1 = map.at("KEY2"); + test_vec2 = test_map.at("KEY2"); + RUNNER_ASSERT(test_vec1.size() == test_vec2.size()); + for (i = 0; i < test_vec1.size(); ++i) { + RUNNER_ASSERT((*test_vec1[i]) == (*test_vec2[i])); + } +} + diff --git a/tests/core/test_shared_ptr.cpp b/tests/core/test_shared_ptr.cpp new file mode 100644 index 0000000..8e59075 --- /dev/null +++ b/tests/core/test_shared_ptr.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_shared_ptr.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test shared ptr + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: SharedPtr_Zero +Description: Tests behaviour of null shared pointer +Expected: pointer should imitate null pointer +*/ +RUNNER_TEST(SharedPtr_Zero) +{ + DPL::SharedPtr ptr; + + RUNNER_ASSERT(!ptr); + RUNNER_ASSERT(!!!ptr); + RUNNER_ASSERT(ptr == DPL::SharedPtr()); +} + +/* +Name: SharedPtr_NonZero +Description: Tests behaviour of not null shared pointer +Expected: pointer should imitate null pointer +*/ +RUNNER_TEST(SharedPtr_NonZero) +{ + DPL::SharedPtr ptr(new char(7)); + + RUNNER_ASSERT(ptr); + RUNNER_ASSERT(!!ptr); + RUNNER_ASSERT(ptr != DPL::SharedPtr()); +} + +/* +Name: SharedPtr_Copy +Description: Tests equality of shared pointer pointing same resource +Expected: pointers should imitate primitive pointer bahaviour +*/ +RUNNER_TEST(SharedPtr_Copy) +{ + DPL::SharedPtr ptr1(new char(7)); + DPL::SharedPtr ptr2(new char(7)); + + RUNNER_ASSERT(ptr1 != ptr2); + + ptr2 = ptr1; + + RUNNER_ASSERT(ptr1 == ptr2); +} + +/* +Name: SharedPtr_Reset +Description: Tests reseting shared pointer +Expected: pointers should imitate primitive pointer bahaviour after reset +*/ +RUNNER_TEST(SharedPtr_Reset) +{ + DPL::SharedPtr ptr(new char(7)); + ptr.Reset(); + + RUNNER_ASSERT(!ptr); + + ptr.Reset(new char); + RUNNER_ASSERT(ptr); +} + +/* +Name: SharedPtr_RefCounting +Description: Tests use count od shared pointer +Expected: counters should be equal for equal pointers + Count number should match expected +*/ +RUNNER_TEST(SharedPtr_RefCounting) +{ + DPL::SharedPtr ptr1(new char(7)); + DPL::SharedPtr ptr2; + + ptr2 = ptr1; + + RUNNER_ASSERT(ptr1 == ptr2); + RUNNER_ASSERT(ptr1.GetUseCount() == ptr2.GetUseCount()); + RUNNER_ASSERT(ptr1.GetUseCount() == 2); +} + +/* +Name: SharedPtr_Operators +Description: Tests use of operator* +Expected: pointers should imitate primitive pointer bahaviour +*/ +RUNNER_TEST(SharedPtr_Operators) +{ + DPL::SharedPtr ptr(new char(7)); + + RUNNER_ASSERT(*ptr == *ptr.Get()); +} diff --git a/tests/core/test_single_instance.cpp b/tests/core/test_single_instance.cpp new file mode 100644 index 0000000..b17d583 --- /dev/null +++ b/tests/core/test_single_instance.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_single_instance.cpp + * @author Slawomir Pajak (s.pajak@partner.samsung.com) + * @version 1.0 + * @brief This file is the implementation file of single instance tests + */ +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +using namespace DPL; + +/* +Name: SingleInstance_lock_release +Description: tests single instance simple case +Expected: all operations succeed, no exceptions +*/ +RUNNER_TEST(SingleInstance_lock_release) +{ + SingleInstance instance; + RUNNER_ASSERT(instance.TryLock("testLockFile")); + + instance.Release(); + //Multiple call should be fine. + instance.Release(); + +} diff --git a/tests/core/test_static_block.cpp b/tests/core/test_static_block.cpp new file mode 100644 index 0000000..b7596ef --- /dev/null +++ b/tests/core/test_static_block.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test_static_block.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 0.1 + * @brief + */ + +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +namespace { +bool ok_namespace = false; +bool ok_class = false; + +STATIC_BLOCK +{ + ok_namespace = true; +} + +struct A +{ + static void init() + { + ok_class = true; + } +}; +STATIC_BLOCK_CLASS( A, init ) +} + +/* +Name: StaticBlockInitCheck +Description: checks if static blocks were run +Expected: variables should be set +*/ +RUNNER_TEST(StaticBlockInitCheck) +{ + RUNNER_ASSERT(ok_namespace); + RUNNER_ASSERT(ok_class); +} diff --git a/tests/core/test_string.cpp b/tests/core/test_string.cpp new file mode 100644 index 0000000..e124376 --- /dev/null +++ b/tests/core/test_string.cpp @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_string.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of string tests + */ +#include +#include +#include +#include +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +unsigned char GetBaseCode(int index); +unsigned char GetBaseCode(int index) +{ + /* 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 + }; + return pr2six[index]; +} + +/* Function adapted from APR library (http://apr.apache.org/) */ +int wbxml_base64_decode(const char *buffer, char **result); +int wbxml_base64_decode(const char *buffer, char **result) +{ + int nbytesdecoded = 0, nprbytes = 0; + const char *bufin = NULL; + char *bufout = NULL; + + if ((buffer == NULL) || (result == NULL)) { + return 0; + } + + /* Initialize output buffer */ + *result = NULL; + + bufin = buffer; + while (GetBaseCode(*(bufin++)) <= 63) {} + + nprbytes = (bufin - buffer) - 1; + nbytesdecoded = ((nprbytes + 3) / 4) * 3; + + /* Malloc result buffer */ + if ((*result = (char*) malloc(nbytesdecoded + 1)) == NULL) { + return 0; + } + memset(*result, 0, nbytesdecoded + 1); + + bufout = *result; + bufin = buffer; + + while (nprbytes > 4) { + *(bufout++) = + (char)(GetBaseCode(*bufin) << 2 | GetBaseCode(bufin[1]) >> 4); + *(bufout++) = + (char)(GetBaseCode(bufin[1]) << 4 | GetBaseCode(bufin[2]) >> 2); + *(bufout++) = (char)(GetBaseCode(bufin[2]) << 6 | GetBaseCode(bufin[3])); + bufin += 4; + nprbytes -= 4; + } + + /* Note: (nprbytes == 1) would be an error, so just ingore that case */ + if (nprbytes > 1) { + *(bufout++) = + (char)(GetBaseCode(*bufin) << 2 | GetBaseCode(bufin[1]) >> 4); + } + if (nprbytes > 2) { + *(bufout++) = + (char)(GetBaseCode(bufin[1]) << 4 | GetBaseCode(bufin[2]) >> 2); + } + if (nprbytes > 3) { + *(bufout++) = (char)(GetBaseCode(bufin[2]) << 6 | GetBaseCode(bufin[3])); + } + + nbytesdecoded -= (4 - nprbytes) & 3; + + return nbytesdecoded; +} + +//#define TEST_CONVERSION(in_string, out_string, buffer_type, function + +const char utf32Encoded[] = + "RDAAAI0wAABvMAAAazAAAHswAAB4MAAAaDAAAAAwAABhMAAAijAAAGwwAACLMAAAkjAAAAAwAACP\ +MAAASzAAAIgwAABfMAAAjDAAAF0wAAAAMAAAZDAAAG0wAABqMAAAiTAAAIAwAAAAMAAARjAAAJAw\ +AABuMAAASjAAAE8wAACEMAAAfjAAAAAwAABRMAAAdTAAAFMwAABIMAAAZjAAAAAwAABCMAAAVTAA\ +AE0wAACGMAAAgTAAAH8wAABXMAAAADAAAJEwAAByMAAAgjAAAFswAABZMAAACgAAANsFAADaBQAA\ +IAAAANQFAADqBQAA6AUAAOEFAADnBQAAIAAAAOAFAADkBQAA5QUAACAAAADiBQAA3AUAACAAAADS\ +BQAA1QUAANYFAADcBQAAIAAAAOcFAADYBQAA3wUAACwAAAAgAAAA6QUAANMFAADXBQAA4wUAACAA\ +AADQBQAA6gUAACAAAADmBQAA0QUAANkFAAAgAAAA3AUAAN4FAADZBQAA3QUAAAoAAACk0AAApMIA\ +AFjHAAAgAAAA4KwAACDHAABwyAAAdKwAAEDHAAAgAAAAhccAACDCAAB8sAAArLkAACAAAADMuQAA\ +mLAAAHzFAAAgAAAAWNUAAOCsAAAgAAAAudIAAMS8AABc1QAAIAAAADCuAAAgwgAAQMcAACAAAABE\ +1QAAlMYAAFjOAAAgAAAASsUAAOSyAAAKAAAAUAAAAGMAAABoAAAAbgAAAAUBAAAHAQAAIAAAAHcA\ +AAAgAAAAdAAAABkBAAAgAAAAQgEAAPMAAABkAAAAegEAACAAAABqAAAAZQAAAHwBAABhAAAAIAAA\ +AGwAAAB1AAAAYgAAACAAAABvAAAAWwEAAG0AAAAgAAAAcwAAAGsAAAByAAAAegAAAHkAAABEAQAA\ +IAAAAGYAAABpAAAAZwAAAC4AAAAKAAAAQgAAAGwAAABvAAAAdwAAAHoAAAB5AAAAIAAAAG4AAABp\ +AAAAZwAAAGgAAAB0AAAALQAAAGYAAAByAAAAdQAAAG0AAABwAAAAcwAAACAAAAB2AAAAZQAAAHgA\ +AAAnAAAAZAAAACAAAABKAAAAYQAAAGMAAABrAAAAIAAAAFEAAAAuAAAACgAAAEYGAAA1BgAAIAAA\ +AC0GAABDBgAASgYAAEUGAAAgAAAARAYAAEcGAAAgAAAAMwYAADEGAAAgAAAAQgYAACcGAAA3BgAA\ +OQYAACAAAABIBgAAMAYAAEgGAAAgAAAANAYAACMGAABGBgAAIAAAADkGAAA4BgAASgYAAEUGAAAg\ +AAAARQYAAEMGAAAqBgAASAYAACgGAAAgAAAAOQYAAEQGAABJBgAAIAAAACsGAABIBgAAKAYAACAA\ +AAAjBgAALgYAADYGAAAxBgAAIAAAAEgGAABFBgAAOgYAAEQGAABBBgAAIAAAACgGAAAsBgAARAYA\ +AC8GAAAgAAAAIwYAADIGAAAxBgAAQgYAACAAAAAKAAAAEgQAACAAAABHBAAAMAQAAEkEAAAwBAAA\ +RQQAACAAAABOBAAAMwQAADAEAAAgAAAANgQAADgEAAA7BAAAIAAAADEEAABLBAAAIAAAAEYEAAA4\ +BAAAQgQAAEAEAABDBAAAQQQAAD8AAAAgAAAAFAQAADAEAAAsAAAAIAAAAD0EAAA+BAAAIAAAAEQE\ +AAAwBAAAOwQAAEwEAABIBAAAOAQAADIEAABLBAAAOQQAACAAAABNBAAAOgQAADcEAAA1BAAAPAQA\ +AD8EAAA7BAAATwQAAEAEAAAhAAAACgAAAKQDAACsAwAAxwMAALkDAADDAwAAxAMAALcDAAAgAAAA\ +sQMAALsDAADOAwAAwAMAALcDAAC+AwAAIAAAALIDAACxAwAAxgMAAK4DAADCAwAAIAAAAMgDAAC3\ +AwAAvAMAAK0DAAC9AwAAtwMAACAAAACzAwAAtwMAACwAAAAgAAAAtAMAAMEDAACxAwAAwwMAALoD\ +AAC1AwAAuwMAAK8DAAC2AwAAtQMAALkDAAAgAAAAxQMAAMADAACtAwAAwQMAACAAAAC9AwAAyQMA\ +ALgDAADBAwAAvwMAAM0DAAAgAAAAugMAAMUDAAC9AwAAzAMAAMIDAAAKAAAAVgAAAGkAAABjAAAA\ +dAAAAG8AAAByAAAAIAAAAGoAAABhAAAAZwAAAHQAAAAgAAAAegAAAHcAAAD2AAAAbAAAAGYAAAAg\ +AAAAQgAAAG8AAAB4AAAAawAAAOQAAABtAAAAcAAAAGYAAABlAAAAcgAAACAAAABxAAAAdQAAAGUA\ +AAByAAAAIAAAAPwAAABiAAAAZQAAAHIAAAAgAAAAZAAAAGUAAABuAAAAIAAAAGcAAAByAAAAbwAA\ +AN8AAABlAAAAbgAAACAAAABTAAAAeQAAAGwAAAB0AAAAZQAAAHIAAAAgAAAARAAAAGUAAABpAAAA\ +YwAAAGgAAAAKAAAAlokAAM6RAAAhcQAAUJYAAONeAAAM/wAAl3oAABZZAAAJZwAAzYUAAClZAAAK\ +AAAACgAAAAAAAAA="; + +const char utf8Encoded[] = + "44GE44KN44Gv44Gr44G744G444Go44CA44Gh44KK44Gs44KL44KS44CA44KP44GL44KI44Gf44KM\ +44Gd44CA44Gk44Gt44Gq44KJ44KA44CA44GG44KQ44Gu44GK44GP44KE44G+44CA44GR44G144GT\ +44GI44Gm44CA44GC44GV44GN44KG44KB44G/44GX44CA44KR44Gy44KC44Gb44GZCteb15og15TX\ +qteo16HXpyDXoNek16Ug16LXnCDXkteV15bXnCDXp9eY158sINep15PXl9ejINeQ16og16bXkdeZ\ +INec157XmdedCu2CpOyKpOydmCDqs6DsnKDsobDqsbTsnYAg7J6F7Iig64G866asIOunjOuCmOyV\ +vCDtlZjqs6Ag7Yq567OE7ZWcIOq4sOyIoOydgCDtlYTsmpTsuZgg7JWK64ukClBjaG7EhcSHIHcg\ +dMSZIMWCw7NkxbogamXFvGEgbHViIG/Fm20gc2tyennFhCBmaWcuCkJsb3d6eSBuaWdodC1mcnVt\ +cHMgdmV4J2QgSmFjayBRLgrZhti1INit2YPZitmFINmE2Ycg2LPYsSDZgtin2LfYuSDZiNiw2Ygg\ +2LTYo9mGINi52LjZitmFINmF2YPYqtmI2Kgg2LnZhNmJINir2YjYqCDYo9iu2LbYsSDZiNmF2LrZ\ +hNmBINio2KzZhNivINij2LLYsdmCIArQkiDRh9Cw0YnQsNGFINGO0LPQsCDQttC40Lsg0LHRiyDR\ +htC40YLRgNGD0YE/INCU0LAsINC90L4g0YTQsNC70YzRiNC40LLRi9C5INGN0LrQt9C10LzQv9C7\ +0Y/RgCEKzqTOrM+HzrnPg8+EzrcgzrHOu8+Oz4DOt86+IM6yzrHPhs6uz4Igz4jOt868zq3Ovc63\ +IM6zzrcsIM60z4HOsc+DzrrOtc67zq/Ots61zrkgz4XPgM6tz4Egzr3Pic64z4HOv8+NIM66z4XO\ +vc+Mz4IKVmljdG9yIGphZ3QgenfDtmxmIEJveGvDpG1wZmVyIHF1ZXIgw7xiZXIgZGVuIGdyb8Of\ +ZW4gU3lsdGVyIERlaWNoCuimlumHjueEoemZkOW7o++8jOeql+WkluacieiXjeWkqQoKAA=="; + +const char asciiEncodedIso1[] = + "ISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZ\ +WltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fgA="; + +const char asciiEncodedUtf32[] = + "IQAAACIAAAAjAAAAJAAAACUAAAAmAAAAJwAAACgAAAApAAAAKgAAACsAAAAsAAAALQAAAC4AAAAv\ +AAAAMAAAADEAAAAyAAAAMwAAADQAAAA1AAAANgAAADcAAAA4AAAAOQAAADoAAAA7AAAAPAAAAD0A\ +AAA+AAAAPwAAAEAAAABBAAAAQgAAAEMAAABEAAAARQAAAEYAAABHAAAASAAAAEkAAABKAAAASwAA\ +AEwAAABNAAAATgAAAE8AAABQAAAAUQAAAFIAAABTAAAAVAAAAFUAAABWAAAAVwAAAFgAAABZAAAA\ +WgAAAFsAAABcAAAAXQAAAF4AAABfAAAAYAAAAGEAAABiAAAAYwAAAGQAAABlAAAAZgAAAGcAAABo\ +AAAAaQAAAGoAAABrAAAAbAAAAG0AAABuAAAAbwAAAHAAAABxAAAAcgAAAHMAAAB0AAAAdQAAAHYA\ +AAB3AAAAeAAAAHkAAAB6AAAAewAAAHwAAAB9AAAAfgAAAAAAAAA="; + +/* +Name: String_ConverterFromASCII +Description: tests construction of string from ascii data +Expected: data stored in buffer should match expected +*/ +RUNNER_TEST(String_ConverterFromASCII) +{ + char* inStr = NULL; + int inSize = wbxml_base64_decode(asciiEncodedIso1, &inStr); + RUNNER_ASSERT(inSize > 0); + RUNNER_ASSERT(NULL != inStr); + inStr[inSize] = '\0'; + { + DPL::String asciiString = DPL::FromASCIIString(inStr); + + std::string result = DPL::ToUTF8String(asciiString); + + RUNNER_ASSERT(strlen(inStr) == result.size()); + + RUNNER_ASSERT(0 == memcmp(inStr, result.c_str(), result.size())); + } + + free(inStr); +} + +/* +Name: String_ConverterFromUTF8 +Description: tests construction of string from UTF-8 data +Expected: data stored in buffer should match expected +*/ +RUNNER_TEST(String_ConverterFromUTF8) +{ + char* inStr = NULL; + int inSize = wbxml_base64_decode(asciiEncodedIso1, &inStr); + RUNNER_ASSERT(inSize > 0); + RUNNER_ASSERT(NULL != inStr); + { + DPL::String asciiString = DPL::FromUTF8String(inStr); + + std::string result = DPL::ToUTF8String(asciiString); + + RUNNER_ASSERT(strlen(inStr) == result.size()); + + RUNNER_ASSERT(0 == memcmp(inStr, result.c_str(), result.size())); + } + + free(inStr); +} + +/* +Name: String_ConverterFromUTF32 +Description: tests construction of string from UTF-32 data +Expected: data stored in buffer should match expected +*/ +RUNNER_TEST(String_ConverterFromUTF32) +{ + wchar_t* inStr = NULL; + int inSize = + wbxml_base64_decode(utf32Encoded, reinterpret_cast(&inStr)); + RUNNER_ASSERT(inSize > 0); + RUNNER_ASSERT(NULL != inStr); + char* outStr = NULL; + int outSize = wbxml_base64_decode(utf8Encoded, &outStr); + RUNNER_ASSERT(outSize > 0); + RUNNER_ASSERT(NULL != outStr); + outStr[outSize] = '\0'; + { + DPL::String utfString = DPL::FromUTF32String(inStr); + std::string result = DPL::ToUTF8String(utfString); + + RUNNER_ASSERT(strlen(outStr) == result.size()); + RUNNER_ASSERT(0 == memcmp(outStr, result.c_str(), result.size())); + + RUNNER_ASSERT(inSize / sizeof(wchar_t) - 1 == utfString.size()); + RUNNER_ASSERT(0 == + memcmp(inStr, &(utfString[0]), utfString.size() * + sizeof(wchar_t))); + } + + free(inStr); +} + +template +void String_TokenizeReal(const DelimiterType& delimiter) +{ + DPL::String str(L".##..abc.#."); + std::vector tokens; + DPL::Tokenize(str, delimiter, std::back_inserter(tokens)); + + std::vector expectedTokens; + for (int i = 0; i < 5; i++) { + expectedTokens.push_back(L""); + } + expectedTokens.push_back(L"abc"); + for (int i = 0; i < 3; i++) { + expectedTokens.push_back(L""); + } + + RUNNER_ASSERT(expectedTokens == tokens); + tokens.clear(); + expectedTokens.clear(); + + DPL::Tokenize(str, delimiter, std::back_inserter(tokens), true); + expectedTokens.push_back(L"abc"); + RUNNER_ASSERT(expectedTokens == tokens); +} + +/* +Name: String_Tokenize +Description: tests of string splitting +Expected: returned substring should match expected values +*/ +RUNNER_TEST(String_Tokenize) +{ + String_TokenizeReal(L"#."); + String_TokenizeReal(L".#"); + String_TokenizeReal(L".....####.###.."); + String_TokenizeReal(DPL::String(L".#")); + + std::vector tokens; + DPL::Tokenize(std::string("abc.def"), '.', std::back_inserter(tokens)); + std::vector expectedTokens; + expectedTokens.push_back("abc"); + expectedTokens.push_back("def"); + + RUNNER_ASSERT(tokens == expectedTokens); +} + +template +void TestInStreams( + std::basic_string argumentInString, + std::basic_string argumentResultString) +{ + typedef std::basic_string + String; + std::basic_istringstream + istream(argumentInString); + int intValue = 0; + double doubleValue = 0.0; + float floatValue = 0.0; + String stringValue; + + istream >> intValue; + RUNNER_ASSERT(!istream.fail()); + istream >> doubleValue; + RUNNER_ASSERT(!istream.fail()); + istream >> floatValue; + RUNNER_ASSERT(!istream.fail()); + istream >> stringValue; + RUNNER_ASSERT(!istream.fail()); + + RUNNER_ASSERT(1 == intValue); + RUNNER_ASSERT(fabs(1.1f - doubleValue) < 0.00001); + RUNNER_ASSERT(fabs(1.1f - floatValue) < 0.00001); + RUNNER_ASSERT(argumentResultString == stringValue); +} + +template +void TestOutStreams( + std::basic_string argumentInString, + std::basic_string argumentResultString) +{ + typedef std::basic_string + String; + + std::basic_ostringstream + ostream; + + int intValue = 1; + double doubleValue = 1.1; + float floatValue = 1.1f; + String stringValue = argumentInString; + + ostream << intValue; + RUNNER_ASSERT(!ostream.fail()); + ostream << doubleValue; + RUNNER_ASSERT(!ostream.fail()); + ostream << floatValue; + RUNNER_ASSERT(!ostream.fail()); + ostream << stringValue; + RUNNER_ASSERT(!ostream.fail()); + + RUNNER_ASSERT(ostream.str() == argumentResultString); +} + +/* +Name: String_Streams +Description: tests of input/output stream +Expected: returned substrign should match expected values +*/ +RUNNER_TEST(String_Streams) +{ + TestInStreams >("1 1.1 1.1 test", "test"); + TestInStreams >(L"1 1.1 1.1 test", L"test"); + TestInStreams(L"1 1.1 1.1 test", L"test"); + TestOutStreams >("test", "11.11.1test"); + TestOutStreams >(L"test", L"11.11.1test"); + TestOutStreams(L"test", L"11.11.1test"); +} + +/* +Name: String_CompareCaseSensitive +Description: tests case sensitive comparision +Expected: strings should be equal +*/ +RUNNER_TEST(String_CompareCaseSensitive) +{ + RUNNER_ASSERT( + DPL::StringCompare( + DPL::FromUTF32String(L"Ala Makota ma żołądkówkę"), + DPL::FromUTF32String(L"Ala Makota ma żołądkówkę")) == 0); +} + +/* +Name: String_CompareCaseInsensitive +Description: tests case insensitive comparision +Expected: strings should be equal +*/ +RUNNER_TEST(String_CompareCaseInsensitive) +{ + RUNNER_ASSERT( + DPL::StringCompare( + DPL::FromUTF32String(L"Ala Makota ma żołądkówkę"), + DPL::FromUTF32String(L"AlA MakOTA ma Å»oŁąDKÓwkę"), + true) == 0); +} + +/* +Name: String_Join +Description: tests joining strings algorithm +Expected: join should take place correctly +*/ +RUNNER_TEST(String_Join) +{ + std::vector strings; + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "/") == ""); + strings.push_back("one"); + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "/") == "one"); + strings.push_back("two"); + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "/") == "one/two"); + strings.push_back("three"); + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "/") == "one/two/three"); + strings.push_back("four"); + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "/") == "one/two/three/four"); + RUNNER_ASSERT(DPL::Join(++strings.begin(), --strings.end(), "/") == "two/three"); + + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "+") == "one+two+three+four"); + RUNNER_ASSERT(DPL::Join(strings.begin(), strings.end(), "delim") == "onedelimtwodelimthreedelimfour"); +} + +/* +Name: String_Trim +Description: tests trimming strings +Expected: trim strings +*/ +RUNNER_TEST(String_Trim) +{ + const std::string str = " value "; + + std::string test1 = str; + DPL::Trim(test1, " "); + RUNNER_ASSERT_MSG(test1 == "value", "Full trim failed"); + + std::string test2 = str; + DPL::TrimLeft(test2, " "); + RUNNER_ASSERT_MSG(test2 == "value ", "Left trim failed"); + + std::string test3 = str; + DPL::TrimRight(test3, " "); + RUNNER_ASSERT_MSG(test3 == " value", "Right trim failed"); + + std::string test4 = str; + DPL::Trim(test4, " ea"); + RUNNER_ASSERT_MSG(test4 == "valu", "Trim failed"); + + std::string test5 = str; + DPL::TrimRight(test5, " v"); + RUNNER_ASSERT_MSG(test5 == " value", "Trim failed"); + + DPL::String test6 = L"--aabbaabb--aa--bb--"; + DPL::Trim(test6, L"-a"); + RUNNER_ASSERT_MSG(test6 == L"bbaabb--aa--bb", "Trim failed"); + + DPL::String test7 = L"--aabbaabb--aa--bb--"; + DPL::Trim(test7, L"-ab"); + RUNNER_ASSERT_MSG(test7 == L"", "Trim to empty failed"); +} diff --git a/tests/core/test_thread.cpp b/tests/core/test_thread.cpp new file mode 100644 index 0000000..8eec1f0 --- /dev/null +++ b/tests/core/test_thread.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_thread.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of thread tests + */ +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +bool g_wasFooDeleted; + +class Foo +{ + public: + int id; + Foo(int i = 0) : id(i) + { + LogDebug("Foo: ctor: " << id); + } + + ~Foo() + { + LogDebug("Foo: dtor: " << id); + g_wasFooDeleted = true; + } + + void Bar() + { + LogDebug("Foo: bar"); + } +}; + +typedef DPL::ThreadLocalVariable TlsFoo; +TlsFoo g_foo; + +class FooThread : + public DPL::Thread +{ + protected: + virtual int ThreadEntry() + { + LogDebug("In thread"); + + RUNNER_ASSERT(!g_foo); + RUNNER_ASSERT(g_foo.IsNull()); + + g_foo = Foo(); + g_foo->Bar(); + + return 0; + } +}; + +/* +Name: Thread_ThreadLocalVariable_FooDeletion +Description: tests local thread variable pattern +Expected: local thread variables should not be affected by other threads +*/ +RUNNER_TEST(Thread_ThreadLocalVariable_FooDeletion) +{ + static TlsFoo staticFooForMain; + staticFooForMain = Foo(1); + + TlsFoo fooForMain; + fooForMain = Foo(2); + + RUNNER_ASSERT(!g_foo); + RUNNER_ASSERT(g_foo.IsNull()); + + g_wasFooDeleted = false; + + FooThread thread1; + thread1.Run(); + thread1.Quit(); + + RUNNER_ASSERT(!g_foo); + RUNNER_ASSERT(g_foo.IsNull()); + + RUNNER_ASSERT(g_wasFooDeleted == true); + + FooThread thread2; + thread2.Run(); + thread2.Quit(); + + RUNNER_ASSERT(!g_foo); + RUNNER_ASSERT(g_foo.IsNull()); +} diff --git a/tests/core/test_type_list.cpp b/tests/core/test_type_list.cpp new file mode 100644 index 0000000..b3e6285 --- /dev/null +++ b/tests/core/test_type_list.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test_type_list.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 0.1 + * @brief + */ + +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: TypeList_TypeCount +Description: tests size of typelist idiom +Expected: size should match +*/ +RUNNER_TEST(TypeList_TypeCount) +{ + typedef DPL::TypeListDecl::Type TestTypeList1; + typedef DPL::TypeListDecl::Type TestTypeList2; + typedef DPL::TypeListDecl<>::Type TestTypeList3; + typedef DPL::TypeList TestTypeList4; + + RUNNER_ASSERT(TestTypeList1::Size == 3); + RUNNER_ASSERT(TestTypeList2::Size == 1); + RUNNER_ASSERT(TestTypeList3::Size == 0); + RUNNER_ASSERT(TestTypeList4::Size == 4); + + RUNNER_ASSERT(TestTypeList4::Tail::Tail::Size == 2); +} diff --git a/tests/core/test_waitable_handle_watch.cpp b/tests/core/test_waitable_handle_watch.cpp new file mode 100644 index 0000000..a456d3c --- /dev/null +++ b/tests/core/test_waitable_handle_watch.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_waitable_handle_watch.cpp + * @author Slawomir Pajak (s.pajak@partner.samsung.com) + * @version 1.0 + * @brief This file is the implementation file of WaitableHandleWatchSupport tests + */ +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +using namespace DPL; + +class TestListener: public WaitableHandleWatchSupport::WaitableHandleListener { +public: + int listenerHitCount; + TestListener() : + listenerHitCount(0) + { + } + virtual ~TestListener() + { + } + virtual void OnWaitableHandleEvent(WaitableHandle /*waitableHandle*/, WaitMode::Type /*mode*/) + { + listenerHitCount++; + } +}; + +class TestWaitableHandleWatch: public WaitableHandleWatchSupport { +public: + virtual ~TestWaitableHandleWatch() + { + } + + virtual Thread *GetInvokerThread() + { + return Thread::GetCurrentThread(); + } + + // Invoke direct invoker + virtual void HandleDirectInvoker() + { + + } + + using WaitableHandleWatchSupport::HandleWatcher; +}; + +/* + Name: WaitableHandleWatchSupport_SingleListener + Description: tests WaitableHandleWatchSupport simple case + Expected: listener is notified + */ +RUNNER_TEST(WaitableHandleWatchSupport_SingleListener) +{ + TestWaitableHandleWatch handleWatch; + WaitableHandle handle = 1; + TestListener listener; + handleWatch.AddWaitableHandleWatch(&listener, handle, WaitMode::Read); + + handleWatch.HandleWatcher(handle, WaitMode::Read); + RUNNER_ASSERT(1 == listener.listenerHitCount); +} + +/* + Name: WaitableHandleWatchSupport_MultipleListener + Description: tests WaitableHandleWatchSupport multiple listeners + Expected: listeners are notified correctly + */ +RUNNER_TEST(WaitableHandleWatchSupport_MultipleListener) +{ + TestWaitableHandleWatch handleWatch; + WaitableHandle handle = 1; + TestListener listenerR1; + TestListener listenerR2; + TestListener listenerW1; + TestListener listenerW2; + handleWatch.AddWaitableHandleWatch(&listenerR1, handle, WaitMode::Read); + handleWatch.AddWaitableHandleWatch(&listenerR2, handle, WaitMode::Read); + handleWatch.AddWaitableHandleWatch(&listenerW1, handle, WaitMode::Write); + handleWatch.AddWaitableHandleWatch(&listenerW2, handle, WaitMode::Write); + + handleWatch.HandleWatcher(handle, WaitMode::Read); + RUNNER_ASSERT(1 == listenerR1.listenerHitCount); + RUNNER_ASSERT(1 == listenerR2.listenerHitCount); + RUNNER_ASSERT(0 == listenerW1.listenerHitCount); + RUNNER_ASSERT(0 == listenerW2.listenerHitCount); + + handleWatch.HandleWatcher(handle, WaitMode::Write); + RUNNER_ASSERT(1 == listenerR1.listenerHitCount); + RUNNER_ASSERT(1 == listenerR2.listenerHitCount); + RUNNER_ASSERT(1 == listenerW1.listenerHitCount); + RUNNER_ASSERT(1 == listenerW2.listenerHitCount); +} + +/* + Name: WaitableHandleWatchSupport_MultipleHandle + Description: tests WaitableHandleWatchSupport multiple handles + Expected: listeners are notified correctly + */ +RUNNER_TEST(WaitableHandleWatchSupport_MultipleHandle) +{ + TestWaitableHandleWatch handleWatch; + TestListener listener; + WaitableHandle handle1 = 1; + WaitableHandle handle2 = 2; + handleWatch.AddWaitableHandleWatch(&listener, handle1, WaitMode::Read); + handleWatch.AddWaitableHandleWatch(&listener, handle2, WaitMode::Read); + handleWatch.AddWaitableHandleWatch(&listener, handle1, WaitMode::Write); + handleWatch.AddWaitableHandleWatch(&listener, handle2, WaitMode::Write); + + handleWatch.HandleWatcher(handle1, WaitMode::Read); + RUNNER_ASSERT(1 == listener.listenerHitCount); + + handleWatch.HandleWatcher(handle1, WaitMode::Write); + RUNNER_ASSERT(2 == listener.listenerHitCount); + + handleWatch.HandleWatcher(handle2, WaitMode::Read); + RUNNER_ASSERT(3 == listener.listenerHitCount); + + handleWatch.HandleWatcher(handle2, WaitMode::Write); + RUNNER_ASSERT(4 == listener.listenerHitCount); +} + +/* + Name: WaitableHandleWatchSupport_AddRemoveListener + Description: tests WaitableHandleWatchSupport removing listeners function + Expected: remaining listeners are notified correctly, removed are not notified + */ +RUNNER_TEST(WaitableHandleWatchSupport_AddRemoveListener) +{ + TestWaitableHandleWatch handleWatch; + TestListener listener; + WaitableHandle handle1 = 1; + WaitableHandle handle2 = 2; + handleWatch.AddWaitableHandleWatch(&listener, handle1, WaitMode::Read); + handleWatch.AddWaitableHandleWatch(&listener, handle2, WaitMode::Read); + handleWatch.AddWaitableHandleWatch(&listener, handle1, WaitMode::Write); + handleWatch.AddWaitableHandleWatch(&listener, handle2, WaitMode::Write); + + handleWatch.HandleWatcher(handle1, WaitMode::Read); + RUNNER_ASSERT(1 == listener.listenerHitCount); + + handleWatch.RemoveWaitableHandleWatch(&listener, handle1, WaitMode::Write); + handleWatch.HandleWatcher(handle1, WaitMode::Write); + RUNNER_ASSERT(1 == listener.listenerHitCount); + + handleWatch.RemoveWaitableHandleWatch(&listener, handle2, WaitMode::Read); + handleWatch.HandleWatcher(handle2, WaitMode::Read); + RUNNER_ASSERT(1 == listener.listenerHitCount); + + handleWatch.HandleWatcher(handle2, WaitMode::Write); + RUNNER_ASSERT(2 == listener.listenerHitCount); +} diff --git a/tests/core/test_zip_input.cpp b/tests/core/test_zip_input.cpp new file mode 100644 index 0000000..c62accb --- /dev/null +++ b/tests/core/test_zip_input.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_zip_input.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of zip input tests + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +const char* PATH_NO_FILE = "/opt/share/wrt/wrt-commons/tests/core/no_such_file"; +const char* PATH_ARCHIVE = "/opt/share/wrt/wrt-commons/tests/core/sample.zip"; +const char* ARCHIVED_FILE = "sample.txt"; +} + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: ZipInput_OpenFailed +Description: tests opening non existing file +Expected: exception throw +*/ +RUNNER_TEST(ZipInput_OpenFailed) +{ + bool opened = true; + + Try + { + DPL::ZipInput zip(PATH_NO_FILE); + (void)zip; + } + Catch(DPL::ZipInput::Exception::OpenFailed) + { + opened = false; + } + + RUNNER_ASSERT(opened == false); +} + +/* +Name: ZipInput_OpenFile +Description: tests opening existing file +Expected: zip stats should mkatch expected +*/ +RUNNER_TEST(ZipInput_OpenFile) +{ + DPL::ZipInput zip(PATH_ARCHIVE); + + FOREACH(iter, zip) + { + LogDebug("---------"); + LogDebug("FileInfo: "); +#define FIELD(X) LogDebug(#X ": " << iter->X) + FIELD(name); + FIELD(comment); + FIELD(compressedSize); + FIELD(uncompressedSize); +#undef FIELD + } +} + +/* +Name: ZipInput_UnzipSingleFile +Description: tests opening existing file and unzipping single file +Expected: right content +*/ +RUNNER_TEST(ZipInput_UnzipSingleFile) +{ + DPL::ZipInput zip(PATH_ARCHIVE); + DPL::ZipInput::File *file = zip.OpenFile(ARCHIVED_FILE); + DPL::AbstractWaitableInputAdapter fileAdapter(file); + DPL::BinaryQueue buffer; + DPL::AbstractWaitableOutputAdapter bufferAdapter(&buffer); + + DPL::Copy(&fileAdapter, &bufferAdapter); + + DPL::ScopedArray data(new char[buffer.Size() + 1]); + buffer.Flatten(data.Get(), buffer.Size()); + data[buffer.Size()] = '\0'; + + RUNNER_ASSERT(std::string(data.Get()) == "test"); +} diff --git a/tests/dao/CMakeLists.txt b/tests/dao/CMakeLists.txt new file mode 100644 index 0000000..88c0e24 --- /dev/null +++ b/tests/dao/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Pawel Sikorski (p.sikorski@samsung.com) +# @version 1.0 +# @brief +# + +# common part +FILE(GLOB DAO_TESTS_SOURCES "${PROJECT_SOURCE_DIR}/tests/dao/*DAO.cpp") + +# target wrt-tests-dao +SET(TARGET_DAO_TEST "wrt-commons-tests-dao") +WRT_TEST_INCLUDE_DIRECTORIES(${TARGET_DAO_TEST} ${PROJECT_SOURCE_DIR}/modules/support/ ${PROJECT_SOURCE_DIR}/modules/widget_interface_dao/include/) +WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_DAO_TEST} ${TARGET_WRT_DAO_RW_LIB} ${TARGET_CUSTOM_HANDLER_DAO_RW_LIB} + ${TARGET_CERTIFICATE_DAO_LIB} ${TARGET_SECURITY_ORIGIN_DAO_LIB} ${TARGET_WIDGET_INTERFACE_DAO_LIB}) + +WRT_TEST_BUILD(${TARGET_DAO_TEST} ${DAO_TESTS_SOURCES} tests_dao.cpp) +WRT_TEST_INSTALL(${TARGET_DAO_TEST}) + +# common installed files +INSTALL(PROGRAMS + ${PROJECT_SOURCE_DIR}/tests/dao/wrt_dao_tests_prepare_db.sh + DESTINATION bin + ) diff --git a/tests/dao/README b/tests/dao/README new file mode 100644 index 0000000..6c60a17 --- /dev/null +++ b/tests/dao/README @@ -0,0 +1,11 @@ +Wrt DAO +System tests. Tests database access layer: widgets information database, global configuration, plugins. +Binary file: wrt-tests-dao. Uses our test framework. Allows to use different types of output. Text output shows results on console - green passed. +To run: +1. Install wrt-extra on target +2. Run wrt-tests-dao --output=text + +Automatic: YES +Included in Daily Build: YES (http://build01.sprc.samsung.pl/browse/LINUXNGWAP-INT) +Included in Gerrit Builds: YES (http://build01.sprc.samsung.pl/browse/LINUXNGWAP-GERRIT) +Number of test cases: 45 \ No newline at end of file diff --git a/tests/dao/TestCases_CertificateDAO.cpp b/tests/dao/TestCases_CertificateDAO.cpp new file mode 100644 index 0000000..729b4a3 --- /dev/null +++ b/tests/dao/TestCases_CertificateDAO.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file TestCases_CertificateDAO.cpp + * @author Slawomir Pajak (s.pajak@partner.samsung.com) + * @version 1.0 + * @brief This file contains tests for certificate dao class. + */ + +#include +#include + +RUNNER_TEST_GROUP_INIT(DAO) + +using namespace CertificateDB; + +namespace { + +class CertificateDAOWrapper { +public: + static CertificateDAO* getCertificateDAO() + { + static CertificateDAOPtr certificateDAO( + new CertificateDB::CertificateDAO(DPL::FromASCIIString("testWidget123"))); + return certificateDAO.get(); + } +}; +} + +/** + * Name: certificate_dao_save_remove_by_certdata + * Description: Tests saves certificateDao object, reads it, and removes it at the end + * using certificate data value. + * Expected: All operations should succeed. + */ +RUNNER_TEST(certificate_dao_save_remove_by_certdata) +{ + CertificateDAO* certificateDAO = CertificateDAOWrapper::getCertificateDAO(); + + CertificateDataList dataList = certificateDAO->getCertificateDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "CertificateDataList should be empty"); + + CertificateData certData(DPL::FromASCIIString("sampleCetificate")); + certificateDAO->setCertificateData(certData, RESULT_ALLOW_ONCE); + + dataList = certificateDAO->getCertificateDataList(); + + RUNNER_ASSERT_MSG(dataList.size() == 1, "CertificateDataList should not be empty"); + RUNNER_ASSERT_MSG((*dataList.begin())->certificate == DPL::FromASCIIString("sampleCetificate"), + "Wrong element in table"); + + RUNNER_ASSERT_MSG(certificateDAO->getResult(**dataList.begin()) == RESULT_ALLOW_ONCE, "Wrong result"); + + certificateDAO->removeCertificateData(certData); + + dataList = certificateDAO->getCertificateDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "CertificateDataList should be empty"); + +} + +/** + * Name: certificate_dao_save_remove_by_result + * Description: Tests saves certificateDao object, reads it, and removes it at the end + * using result value. + * Expected: All operations should succeed. + */ +RUNNER_TEST(certificate_dao_save_remove_by_result) +{ + CertificateDAO* certificateDAO = CertificateDAOWrapper::getCertificateDAO(); + + CertificateDataList dataList = certificateDAO->getCertificateDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "CertificateDataList should be empty"); + + CertificateData certData(DPL::FromASCIIString("sampleCetificate1")); + certificateDAO->setCertificateData(certData, RESULT_ALLOW_ALWAYS); + + CertificateData certData2(DPL::FromASCIIString("sampleCetificate2")); + certificateDAO->setCertificateData(certData2, RESULT_ALLOW_ALWAYS); + + dataList = certificateDAO->getCertificateDataList(); + RUNNER_ASSERT_MSG(dataList.size() == 2, "CertificateDataList should not be empty"); + + certificateDAO->removeCertificateData(RESULT_ALLOW_ALWAYS); + dataList = certificateDAO->getCertificateDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "CertificateDataList should be empty"); +} + +/** + * Name: certificate_dao_update + * Description: Tests update of certificateDao object. + * Expected: All operations should succeed. + */ +RUNNER_TEST(certificate_dao_update) +{ + CertificateDAO* certificateDAO = CertificateDAOWrapper::getCertificateDAO(); + + CertificateDataList dataList = certificateDAO->getCertificateDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "CertificateDataList should be empty"); + + CertificateData certData(DPL::FromASCIIString("sampleCetificate3")); + certificateDAO->setCertificateData(certData, RESULT_ALLOW_ONCE); + + dataList = certificateDAO->getCertificateDataList(); + RUNNER_ASSERT_MSG(dataList.size() == 1, "CertificateDataList should not be empty"); + RUNNER_ASSERT_MSG((*dataList.begin())->certificate == DPL::FromASCIIString("sampleCetificate3"), + "Wrong element in table"); + RUNNER_ASSERT_MSG(certificateDAO->getResult(**dataList.begin()) == RESULT_ALLOW_ONCE, "Wrong result"); + + certificateDAO->setCertificateData(certData, RESULT_DENY_ALWAYS); + dataList = certificateDAO->getCertificateDataList(); + RUNNER_ASSERT_MSG(dataList.size() == 1, "CertificateDataList should not be empty"); + RUNNER_ASSERT_MSG((*dataList.begin())->certificate == DPL::FromASCIIString("sampleCetificate3"), + "Wrong element in table"); + RUNNER_ASSERT_MSG(certificateDAO->getResult(**dataList.begin()) == RESULT_DENY_ALWAYS, "Wrong result"); + + certificateDAO->removeCertificateData(certData); + dataList = certificateDAO->getCertificateDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "CertificateDataList should be empty"); +} + +/** + * Name: certificate_dao_equality_operator + * Description: Tests CertificateData equality operators. + * Expected: All operations should succeed. + */ +RUNNER_TEST(certificate_dao_equality_operator) +{ + CertificateData certData1(DPL::FromASCIIString("sampleCetificate1")); + CertificateData certData2(DPL::FromASCIIString("sampleCetificate1")); + CertificateData certData3(DPL::FromASCIIString("sampleCetificate2")); + + RUNNER_ASSERT_MSG(certData1 == certData2, "Object should be equal"); + RUNNER_ASSERT_MSG(certData1 != certData3, "Object should not be equal"); + RUNNER_ASSERT_MSG(certData2 != certData3, "Object should not be equal"); +} + diff --git a/tests/dao/TestCases_CustomHandlerDAO.cpp b/tests/dao/TestCases_CustomHandlerDAO.cpp new file mode 100644 index 0000000..d606b03 --- /dev/null +++ b/tests/dao/TestCases_CustomHandlerDAO.cpp @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file TestCases_CustomHandlerDAO.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief This file contains tests for custom handler dao class. + */ + +#include +#include +#include +#include + +using namespace CustomHandlerDB; + +RUNNER_TEST_GROUP_INIT(DAO) + +namespace { +const DPL::String P_TARGET(L"p_target"); +const DPL::String P_BASE_URL(L"p_base_url"); +const DPL::String P_URL(L"p_url"); +const DPL::String P_TITLE(L"p_title"); + +const DPL::String C_TARGET(L"c_target"); +const DPL::String C_BASE_URL(L"c_base_url"); +const DPL::String C_URL(L"c_url"); +const DPL::String C_TITLE(L"c_title"); + +void checkHandlersExistence(CustomHandlerDAOReadOnly& dao, + bool protocol, + bool content) +{ + CustomHandlerDB::CustomHandlerPtr handler; + handler = dao.getProtocolHandler(P_TARGET, P_URL); + RUNNER_ASSERT_MSG((!!handler) == protocol, "Protocol handler check"); + handler = dao.getContentHandler(C_TARGET, C_URL); + RUNNER_ASSERT_MSG((!!handler) == content, "Content handler check"); +} +} // namespace + +RUNNER_TEST(custom_handler_empty_db_read) +{ + CustomHandlerDAOReadOnly dao(DPL::String(L"test")); +} + +RUNNER_TEST(custom_handlers) +{ + CustomHandlerDAOReadOnly dao_ro(L"test"); + CustomHandlerDAO dao_rw(L"test"); + + CustomHandlerDB::CustomHandlerPtr handler; + CustomHandlerDB::CustomHandler p_handler; + p_handler.target = P_TARGET; + p_handler.base_url = P_BASE_URL; + p_handler.url = P_URL; + p_handler.title = P_TITLE; + p_handler.user_decision = Agreed; + + // initial check + checkHandlersExistence(dao_ro, false, false); + + // Protocol handler registration + dao_rw.registerProtocolHandler(p_handler); + checkHandlersExistence(dao_ro, true, false); + + handler = dao_ro.getProtocolHandler(P_TARGET, P_URL); + RUNNER_ASSERT(handler); + RUNNER_ASSERT(handler->target == P_TARGET); + RUNNER_ASSERT(handler->base_url == P_BASE_URL); + RUNNER_ASSERT(handler->url == P_URL); + RUNNER_ASSERT(handler->title == P_TITLE); + RUNNER_ASSERT(handler->user_decision == Agreed); + + // Content handler registration + CustomHandlerDB::CustomHandler c_handler; + c_handler.target = C_TARGET; + c_handler.base_url = C_BASE_URL; + c_handler.url = C_URL; + c_handler.title = C_TITLE; + c_handler.user_decision = DeclinedPermanently; + + dao_rw.registerContentHandler(c_handler); + checkHandlersExistence(dao_ro, true, true); + handler = dao_ro.getContentHandler(C_TARGET, C_URL); + + RUNNER_ASSERT(handler); + RUNNER_ASSERT(handler->target == C_TARGET); + RUNNER_ASSERT(handler->base_url == C_BASE_URL); + RUNNER_ASSERT(handler->url == C_URL); + RUNNER_ASSERT(handler->title == C_TITLE); + RUNNER_ASSERT(handler->user_decision == DeclinedPermanently); + + // Handler unregistration + dao_rw.unregisterProtocolHandler(P_TARGET, P_URL); + checkHandlersExistence(dao_ro, false, true); + + // Nonexistent unregistration + dao_rw.unregisterContentHandler(L"blah", L"blah"); + checkHandlersExistence(dao_ro, false, true); + + // Cleanup + dao_rw.unregisterContentHandler(C_TARGET, C_URL); + checkHandlersExistence(dao_ro, false, false); +} + +RUNNER_TEST(custom_handler_unregister) +{ + CustomHandlerDAOReadOnly dao_ro(L"test"); + CustomHandlerDAO dao_rw(L"test"); + + // initial check + checkHandlersExistence(dao_ro, false, false); + + CustomHandlerDB::CustomHandler p_handler; + p_handler.target = P_TARGET; + p_handler.base_url = P_BASE_URL; + p_handler.url = P_URL; + p_handler.title = P_TITLE; + p_handler.user_decision = Agreed; + + // Protocol handler registration + dao_rw.registerProtocolHandler(p_handler); + checkHandlersExistence(dao_ro, true, false); + + // Content handler registration + CustomHandlerDB::CustomHandler c_handler; + c_handler.target = C_TARGET; + c_handler.base_url = C_BASE_URL; + c_handler.url = C_URL; + c_handler.title = C_TITLE; + c_handler.user_decision = DeclinedPermanently; + + dao_rw.registerContentHandler(c_handler); + checkHandlersExistence(dao_ro, true, true); + + // Handler unregistration + dao_rw.unregisterProtocolHandler(P_TARGET, P_URL, P_BASE_URL); + checkHandlersExistence(dao_ro, false, true); + + // Cleanup + dao_rw.unregisterContentHandler(C_TARGET, C_URL, C_BASE_URL); + checkHandlersExistence(dao_ro, false, false); +} + +RUNNER_TEST(custom_handler_update) +{ + CustomHandlerDAOReadOnly dao_ro(L"test"); + CustomHandlerDAO dao_rw(L"test"); + + // initial check + checkHandlersExistence(dao_ro, false, false); + + CustomHandlerDB::CustomHandler p_handler; + p_handler.target = P_TARGET; + p_handler.base_url = P_BASE_URL; + p_handler.url = P_URL; + p_handler.title = P_TITLE; + p_handler.user_decision = Agreed; + + // Protocol handler registration + dao_rw.registerProtocolHandler(p_handler); + checkHandlersExistence(dao_ro, true, false); + + // Content handler registration + CustomHandlerDB::CustomHandlerPtr handler; + CustomHandlerDB::CustomHandler c_handler; + c_handler.target = C_TARGET; + c_handler.base_url = C_BASE_URL; + c_handler.url = C_URL; + c_handler.title = C_TITLE; + c_handler.user_decision = DeclinedPermanently; + + dao_rw.registerContentHandler(c_handler); + checkHandlersExistence(dao_ro, true, true); + + p_handler.title = L"newTitle"; + p_handler.user_decision = AgreedPermanently; + + // Protocol handler update + dao_rw.registerProtocolHandler(p_handler); + + handler = dao_ro.getProtocolHandler(P_TARGET, P_URL); + RUNNER_ASSERT(handler); + RUNNER_ASSERT(handler->target == P_TARGET); + RUNNER_ASSERT(handler->base_url == P_BASE_URL); + RUNNER_ASSERT(handler->url == P_URL); + RUNNER_ASSERT(handler->title == L"newTitle"); + RUNNER_ASSERT(handler->user_decision == AgreedPermanently); + + c_handler.title = L"newTitle2"; + c_handler.user_decision = Agreed; + // Content handler update + dao_rw.registerContentHandler(c_handler); + + handler = dao_ro.getContentHandler(C_TARGET, C_URL); + + RUNNER_ASSERT(handler); + RUNNER_ASSERT(handler->target == C_TARGET); + RUNNER_ASSERT(handler->base_url == C_BASE_URL); + RUNNER_ASSERT(handler->url == C_URL); + RUNNER_ASSERT(handler->title == L"newTitle2"); + RUNNER_ASSERT(handler->user_decision == Agreed); + + // Handler unregistration + dao_rw.removeWidgetProtocolHandlers(); + checkHandlersExistence(dao_ro, false, true); + + // Cleanup + dao_rw.removeWidgetContentHandlers(); + checkHandlersExistence(dao_ro, false, false); +} + +RUNNER_TEST(custom_handler_get_active_protocol) +{ + CustomHandlerDAOReadOnly dao_ro(L"test"); + CustomHandlerDAO dao_rw(L"test"); + + CustomHandlerDB::CustomHandler p_handler; + p_handler.target = P_TARGET; + p_handler.base_url = P_BASE_URL; + p_handler.url = L"url1"; + p_handler.title = L"title1"; + p_handler.user_decision = DeclinedPermanently; + // Protocol handler registration + dao_rw.registerProtocolHandler(p_handler); + + CustomHandlerDB::CustomHandlerPtr handler = dao_ro.getActivProtocolHandler(P_TARGET); + RUNNER_ASSERT(!handler); + + CustomHandlerDB::CustomHandler p_handler2; + p_handler2.target = P_TARGET; + p_handler2.base_url = P_BASE_URL; + p_handler2.url = L"url2"; + p_handler2.title = L"title2"; + p_handler2.user_decision = AgreedPermanently; + // Protocol handler registration + dao_rw.registerProtocolHandler(p_handler2); + + handler = dao_ro.getActivProtocolHandler(P_TARGET); + RUNNER_ASSERT(handler); + RUNNER_ASSERT(handler->target == P_TARGET); + RUNNER_ASSERT(handler->base_url == P_BASE_URL); + RUNNER_ASSERT(handler->url == L"url2"); + RUNNER_ASSERT(handler->title == L"title2"); + RUNNER_ASSERT(handler->user_decision == AgreedPermanently); + + // Handler unregistration + dao_rw.removeWidgetProtocolHandlers(); +} + +RUNNER_TEST(custom_handler_get_active_content) +{ + CustomHandlerDAOReadOnly dao_ro(L"test"); + CustomHandlerDAO dao_rw(L"test"); + + CustomHandlerDB::CustomHandler c_handler; + c_handler.target = C_TARGET; + c_handler.base_url = C_BASE_URL; + c_handler.url = L"url2"; + c_handler.title = L"title2"; + c_handler.user_decision = DeclinedPermanently; + // Protocol handler registration + dao_rw.registerContentHandler(c_handler); + + CustomHandlerDB::CustomHandlerPtr handler = dao_ro.getActivProtocolHandler(C_TARGET); + RUNNER_ASSERT(!handler); + + CustomHandlerDB::CustomHandler c_handler2; + c_handler2.target = C_TARGET; + c_handler2.base_url = C_BASE_URL; + c_handler2.url = L"url1"; + c_handler2.title = C_TITLE; + c_handler2.user_decision = Agreed; + // Protocol handler registration + dao_rw.registerContentHandler(c_handler2); + + handler = dao_ro.getActivContentHandler(C_TARGET); + RUNNER_ASSERT(handler); + RUNNER_ASSERT(handler->target == C_TARGET); + RUNNER_ASSERT(handler->base_url == C_BASE_URL); + RUNNER_ASSERT(handler->url == L"url1"); + RUNNER_ASSERT(handler->title == C_TITLE); + RUNNER_ASSERT(handler->user_decision == Agreed); + + // Handler unregistration + dao_rw.removeWidgetContentHandlers(); +} diff --git a/tests/dao/TestCases_FeatureDAO.cpp b/tests/dao/TestCases_FeatureDAO.cpp new file mode 100644 index 0000000..f01355c --- /dev/null +++ b/tests/dao/TestCases_FeatureDAO.cpp @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file TestCases_FeatureDAO.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains tests for feature dao class. + */ + +#include +#include +#include +#include +#include + +using namespace WrtDB; + +#define RUNNER_ASSERT_WHAT_EQUALS(in, test) \ + { std::string tmp(in); \ + RUNNER_ASSERT_MSG(tmp == test, "Equals: [" + tmp + "]"); } + +RUNNER_TEST_GROUP_INIT(DAO) + +/* + * Name: feature_dao_test_register_features + * Description: Checks if plugin registeration performs features registration + * and if registration is made properly + * Expected: registrartion should succeed + */ +RUNNER_TEST(feature_dao_test_register_features) +{ + PluginHandle plHandle; + { + std::string libraryPath("nfp1 lib_path"); + std::string libraryName("nfp1"); + + PluginMetafileData pluginData; + pluginData.m_libraryName = libraryName; + + plHandle = PluginDAO::registerPlugin(pluginData, libraryPath); + RUNNER_ASSERT(PluginDAO::isPluginInstalled(libraryName) == true); + + FeatureHandleList old = FeatureDAOReadOnly::GetHandleList(); + PluginMetafileData::Feature f; + f.m_name = std::string("new_f1"); + + FeatureHandle handle = FeatureDAO::RegisterFeature(f, plHandle); + RUNNER_ASSERT_MSG(handle != -1, "Already registered"); + RUNNER_ASSERT_MSG(old.size() < FeatureDAOReadOnly::GetHandleList().size(), + "New feature should be saved"); + + FeatureDAOReadOnly dao(handle); + + RUNNER_ASSERT_WHAT_EQUALS(dao.GetName(), "new_f1"); + plHandle = dao.GetPluginHandle(); + } + + { + FeatureHandleList old = FeatureDAOReadOnly::GetHandleList(); + + PluginMetafileData::Feature f; + f.m_name = std::string("new_f2"); + + FeatureHandle handle = FeatureDAO::RegisterFeature(f, plHandle); + RUNNER_ASSERT_MSG(handle != -1, "Already registered"); + RUNNER_ASSERT_MSG(old.size() < FeatureDAOReadOnly::GetHandleList().size(), + "New feature should be saved"); + + FeatureDAOReadOnly dao(handle); + + RUNNER_ASSERT_MSG(plHandle == dao.GetPluginHandle(), + "New plugin registered (should be old used)"); + + FeatureDAO::UnregisterFeature(handle); + PluginDAO::unregisterPlugin(plHandle); + } +} + +/* + * Name: feature_dao_test_get_feature_handle + * Description: Checks GetFeatureHandleListForPlugin + * Expected: no errors found + * directly + */ +RUNNER_TEST(feature_dao_test_get_feature_handle) +{ + PluginHandleSetPtr plugins = + PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_COMPLETED); + + RUNNER_ASSERT(plugins->size() == 5); + + FOREACH(it, *plugins) { + FeatureHandleListPtr featureListPtr = + FeatureDAOReadOnly::GetFeatureHandleListForPlugin(*it); + int size = featureListPtr->size(); + + switch(*it) + { + case 1: + RUNNER_ASSERT(size == 1); + break; + case 2: + RUNNER_ASSERT(size == 0); + break; + case 3: + RUNNER_ASSERT(size == 0); + break; + case 4: + RUNNER_ASSERT(size == 3); + break; + case 5: + RUNNER_ASSERT(size == 0); + break; + default: + RUNNER_ASSERT_MSG(false, "Wrong plugin handle"); + break; + } + } +} + +/* + * Name: feature_dao_test_get_device_capability + * Description: Checks GetDeviceCapability + * Expected: no errors found + * directly + */ +RUNNER_TEST(feature_dao_test_get_device_capability) +{ + RUNNER_ASSERT(FeatureDAOReadOnly::GetDeviceCapability(L"feature1").size() == 1); + RUNNER_ASSERT(FeatureDAOReadOnly::GetDeviceCapability(L"feature2").size() == 2); + RUNNER_ASSERT(FeatureDAOReadOnly::GetDeviceCapability(L"feature3").size() == 1); + RUNNER_ASSERT(FeatureDAOReadOnly::GetDeviceCapability(L"feature4").size() == 0); +} + +/* + * Name: feature_dao_test_unregister + * Description: Checks UnregisterFeature + * Expected: no errors found + */ +RUNNER_TEST(feature_dao_test_unregister) +{ + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled("feature5") == false); + unsigned int size = FeatureDAOReadOnly::GetHandleList().size(); + + PluginHandle plHandle; + PluginMetafileData pluginData; + pluginData.m_libraryName = "nfp1 lib_path"; + plHandle = PluginDAO::registerPlugin(pluginData, "lib_path"); + + PluginMetafileData::Feature f0; + f0.m_name = std::string("feature5"); + f0.m_deviceCapabilities.insert("1devicecap"); + f0.m_deviceCapabilities.insert("2devicecap"); + f0.m_deviceCapabilities.insert("3devicecap"); + + FeatureHandle handle0 = FeatureDAO::RegisterFeature(f0, plHandle); + RUNNER_ASSERT_MSG(handle0 != -1, "Already registered"); + + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled(handle0) == true); + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled("feature5") == true); + RUNNER_ASSERT(FeatureDAOReadOnly::GetHandleList().size() == size + 1); + + FeatureDAO::UnregisterFeature(handle0); + + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled(handle0) == false); + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled("feature5") == false); + RUNNER_ASSERT(FeatureDAOReadOnly::GetHandleList().size() == size); + + PluginMetafileData::Feature f1; + f1.m_name = std::string("feature5"); + + FeatureHandle handle1 = FeatureDAO::RegisterFeature(f1, plHandle); + RUNNER_ASSERT_MSG(handle1 != -1, "Already registered"); + + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled(handle1) == true); + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled("feature5") == true); + RUNNER_ASSERT(FeatureDAOReadOnly::GetHandleList().size() == size + 1); + + FeatureDAO::UnregisterFeature(handle1); + + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled(handle1) == false); + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled("feature5") == false); + RUNNER_ASSERT(FeatureDAOReadOnly::GetHandleList().size() == size); + + PluginDAO::unregisterPlugin(plHandle); +} + +/* + * Name: feature_dao_test_get_device_capabilities + * Description: Checks GetDeviceCapabilities + * Expected: no errors found + */ +RUNNER_TEST(feature_dao_test_get_device_capabilities) +{ + FeatureDAOReadOnly f1("feature1"); + RUNNER_ASSERT(f1.GetDeviceCapabilities().size() == 1); + + FeatureDAOReadOnly f2("feature2"); + RUNNER_ASSERT(f2.GetDeviceCapabilities().size() == 2); + + FeatureDAOReadOnly f3("feature3"); + RUNNER_ASSERT(f3.GetDeviceCapabilities().size() == 1); + + FeatureDAOReadOnly f4("feature4"); + RUNNER_ASSERT(f4.GetDeviceCapabilities().size() == 0); +} + +/* + * Name: feature_dao_test_get_names + * Description: Checks GetNames + * Expected: no errors found + * directly + */ +RUNNER_TEST(feature_dao_test_get_names) +{ + FeatureDAOReadOnly::NameMap names = FeatureDAOReadOnly::GetNames(); + + RUNNER_ASSERT(names.size() == 4); + + int count = 0; + FOREACH(n, names){ + if(n->second == "feature1" || n->second == "feature2" || + n->second == "feature3" || n->second == "feature4") + count++; + else RUNNER_ASSERT_MSG(false, "Wrong feature name"); + } + + RUNNER_ASSERT(count == 4); +} + +/* + * Name: feature_dao_test_dev_cap_with_feature_handle + * Description: Checks GetDevCapWithFeatureHandle + * Expected: no errors found + */ +RUNNER_TEST(feature_dao_test_dev_cap_with_feature_handle) +{ + FeatureDAOReadOnly::DeviceCapabilitiesMap map = FeatureDAOReadOnly::GetDevCapWithFeatureHandle(); + RUNNER_ASSERT(map.size() == 4); + + int count = 0; + FOREACH(n, map){ + if(n->second == "devicecap1" || n->second == "devicecap2" || + n->second == "devicecap3" || n->second == "devicecap4") + count++; + else RUNNER_ASSERT_MSG(false, "Wrong device capability"); + } + + RUNNER_ASSERT(count == 4); +} + + +/* + * Name: feature_dao_test_get_features + * Description: Checks GetFeatures + * Expected: no errors + */ +RUNNER_TEST(feature_dao_test_get_features) +{ +//tests commented because internal error occured due to many GetFeatures() calls +// std::list fs0(4); +// RUNNER_ASSERT(FeatureDAOReadOnly::GetFeatures(fs0).size() == 0); +// +// std::list fs1(4); +// fs1.push_front("feature"); +// fs1.push_front("feature2"); +// RUNNER_ASSERT(FeatureDAOReadOnly::GetFeatures(fs1).size() == 2); +// std::list fs2(4); +// fs2.push_front("feature"); +// fs2.push_front("feature2"); +// RUNNER_ASSERT(FeatureDAOReadOnly::GetFeatures(fs2).size() == 1); + + std::list fs3(4); + fs3.push_front("feature1"); + fs3.push_front("feature2"); + fs3.push_front("feature3"); + fs3.push_front("feature4"); + RUNNER_ASSERT(FeatureDAOReadOnly::GetFeatures(fs3).size() == 4); +} + +/* + * Name: feature_dao_test_get_feature_properties + * Description: Checks properties of inserted features + * Expected: properties of features should match values inserted to database + * directly + */ +RUNNER_TEST(feature_dao_test_get_feature_properties) +{ + { + FeatureDAOReadOnly dao("feature1"); + RUNNER_ASSERT_WHAT_EQUALS(dao.GetName(), "feature1"); + RUNNER_ASSERT_WHAT_EQUALS(dao.GetLibraryName(), "plugin1"); + RUNNER_ASSERT_WHAT_EQUALS(dao.GetLibraryPath(), ""); + } + + { + FeatureDAOReadOnly dao("feature2"); + RUNNER_ASSERT_WHAT_EQUALS(dao.GetName(), "feature2"); + RUNNER_ASSERT_WHAT_EQUALS(dao.GetLibraryName(), "p4"); + RUNNER_ASSERT_WHAT_EQUALS(dao.GetLibraryPath(), "path_to_p4"); + } + + { + FeatureDAOReadOnly dao("feature3"); + RUNNER_ASSERT_WHAT_EQUALS(dao.GetName(), "feature3"); + RUNNER_ASSERT_WHAT_EQUALS(dao.GetLibraryName(), "p4"); + RUNNER_ASSERT_WHAT_EQUALS(dao.GetLibraryPath(), "path_to_p4"); + } +} + +/* + * Name: feature_dao_test_feature_constructor_name + * Description: - + * Expected: - + * + * TODO: test + */ +RUNNER_TEST(feature_dao_test_feature_constructor_name) +{ + std::list preinstalled; + preinstalled.push_back("feature1"); + preinstalled.push_back("feature2"); + preinstalled.push_back("feature3"); + preinstalled.push_back("feature4"); + + FOREACH(it, preinstalled) + { + FeatureDAOReadOnly dao(*it); + RUNNER_ASSERT_WHAT_EQUALS(dao.GetName(), *it); + } + + //TODO check exception that may occur (feature does not exist) +} + +/* + * Name: feature_dao_test_feature_handle_list + * Description: Checks if list of installed features is returend correctly + * Expected: list size should be at last equal number of preinserted features + */ +RUNNER_TEST(feature_dao_test_feature_handle_list) +{ + RUNNER_ASSERT(FeatureDAOReadOnly::GetHandleList().size() == 4); +} + +/* + * Name: feature_dao_test_is_feature_installed + * Description: Checks if installed features are showed correctly. + * Expected: correct installed features should be present + */ +RUNNER_TEST(feature_dao_test_is_feature_installed) +{ + //installed + { + std::list preinstalled; + preinstalled.push_back("feature1"); + preinstalled.push_back("feature2"); + preinstalled.push_back("feature3"); + preinstalled.push_back("feature4"); + + FOREACH(it, preinstalled) + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled(*it)); + } + + //not installed + { + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled( + "not_installed1") == false); + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled( + "plugin1") == false); + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled("") == false); + RUNNER_ASSERT(FeatureDAOReadOnly::isFeatureInstalled("ff") == false); + } +} + +/* + * Name: feature_dao_test_is_device_capab_installed + * Description: Checks if FeatureDAOReadOnly::isDeviceCapabilityInstalled works + * correctly. + * Expected: correct capabilities should be present + */ +RUNNER_TEST(feature_dao_test_is_device_capab_installed) +{ + //installed + std::list preinstalled; + preinstalled.push_back("devicecap1"); + preinstalled.push_back("devicecap2"); + preinstalled.push_back("devicecap3"); + preinstalled.push_back("devicecap4"); + + FOREACH(it, preinstalled) + RUNNER_ASSERT(FeatureDAOReadOnly::isDeviceCapabilityInstalled(*it)); + + //not installed + std::list notinstalled; + notinstalled.push_back("notinstalled1"); + notinstalled.push_back("plugin1"); + notinstalled.push_back(""); + notinstalled.push_back("ff"); + + FOREACH(it, notinstalled) + RUNNER_ASSERT(!FeatureDAOReadOnly::isDeviceCapabilityInstalled(*it)); +} + +#undef RUNNER_ASSERT_WHAT_EQUALS diff --git a/tests/dao/TestCases_PluginDAO.cpp b/tests/dao/TestCases_PluginDAO.cpp new file mode 100644 index 0000000..091d8ed --- /dev/null +++ b/tests/dao/TestCases_PluginDAO.cpp @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file TestCases_PluginDAO.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains tests for feature dao class. + */ + +#include +#include +#include +#include +#include +//#include +#include +#include + +using namespace WrtDB; + +#define RUNNER_ASSERT_WHAT_EQUALS(in, test) \ + { std::string tmp(in); \ + RUNNER_ASSERT_MSG(tmp == test, "Equals: [" + tmp + "]"); } + +RUNNER_TEST_GROUP_INIT(DAO) + +/* + * Name: plugin_dao_test_register_plugins + * Description: registers new plugin and check if it was correctly registered + * Expected: plugin should be correctly registered + */ +RUNNER_TEST(plugin_dao_test_register_plugins) +{ + { + std::string libraryPath("np1 lib_path"); + std::string libraryName("np1"); + + PluginMetafileData pluginData; + pluginData.m_libraryName = libraryName; + + PluginHandle handle = PluginDAO::registerPlugin(pluginData, libraryPath); + PluginDAO::setPluginInstallationStatus( + handle, + PluginDAO:: + INSTALLATION_COMPLETED); + RUNNER_ASSERT(PluginDAO::isPluginInstalled(libraryName) == true); + + PluginDAO dao(handle); + std::string tmp; + tmp = dao.getLibraryPath(); //do for each + RUNNER_ASSERT_MSG(tmp == libraryPath, "Equals: " + tmp); + + unsigned int size = PluginDAO::getPluginHandleList().size(); + PluginDAO::unregisterPlugin(handle); + RUNNER_ASSERT(PluginDAO::getPluginHandleList().size() == size - 1); + } + + { + std::string libraryName("np2"); + + PluginMetafileData pluginData; + pluginData.m_libraryName = libraryName; + + PluginHandle handle = PluginDAO::registerPlugin(pluginData, ""); + PluginDAO::setPluginInstallationStatus( + handle, + PluginDAO:: + INSTALLATION_COMPLETED); + RUNNER_ASSERT(PluginDAO::isPluginInstalled(libraryName) == true); + + PluginDAO dao(handle); + RUNNER_ASSERT(dao.getLibraryPath() == ""); + + unsigned int size = PluginDAO::getPluginHandleList().size(); + PluginDAO::unregisterPlugin(handle); + RUNNER_ASSERT(PluginDAO::getPluginHandleList().size() == size - 1); + } +} + +/* + * Name: plugin_dao_test_register_plugin_implemented_object + * Description: registers new PluginImplementedObject + * and check if it was correctly registered + * Expected: plugin dao shoudld be upodated with PluginImplementedObject + */ +RUNNER_TEST(plugin_dao_test_register_plugin_implemented_object) +{ + { + std::string libraryPath("np3 lib_path"); + std::string libraryName("np3"); + + PluginMetafileData pluginData; + pluginData.m_libraryName = libraryName; + + PluginHandle handle = + PluginDAO::registerPlugin(pluginData, libraryPath); + RUNNER_ASSERT(PluginDAO::isPluginInstalled(libraryName) == true); + + std::string object1("object1"); + std::string object2("object2"); + PluginDAO::registerPluginImplementedObject(object1, handle); + PluginDAO::registerPluginImplementedObject(object2, handle); + + PluginHandle retHandle1 = + PluginDAO::getPluginHandleForImplementedObject(object1); + PluginHandle retHandle2 = + PluginDAO::getPluginHandleForImplementedObject(object1); + RUNNER_ASSERT(retHandle1 == handle); + RUNNER_ASSERT(retHandle2 == handle); + } +} + +/* + * Name: plugin_dao_test_get_root_plugin_handle_list + * Description: test of returning root plugin handle list + * Expected: - + */ +RUNNER_TEST(plugin_dao_test_get_root_plugin_handle_list) +{ + PluginHandleList handles = PluginDAOReadOnly::getRootPluginHandleList(); + RUNNER_ASSERT(handles.size() == 3); + + int count = 0; + FOREACH(n, handles){ + if(*n == 2 || *n == 3 || *n == 5) + count++; + else RUNNER_ASSERT_MSG(false, "Wrong plugin handle"); + } + + RUNNER_ASSERT(count == 3); +} + +/* + * Name: plugin_dao_test_get_implemented_objects + * Description: test of returning plugin handle list + * Expected: - + */ +RUNNER_TEST(plugin_dao_test_get_implemented_objects) +{ + ImplementedObjectsList handles = PluginDAOReadOnly::getImplementedObjects(); + RUNNER_ASSERT(handles.size() == 6); + + int count = 0; + FOREACH(n, handles){ + if(*n == "" || *n == "Plugin_3_Object_A" || *n == "Plugin_4_Object_A" || + *n == "Plugin_4_Object_B" || *n == "Plugin_4_Object_C" || *n == "Plugin_5_Object_A") + count++; + else RUNNER_ASSERT_MSG(false, "Wrong implemented object"); + } + + RUNNER_ASSERT(count == 6); +} + +/* + * Name: plugin_dao_test_register_plugin_implemented_object + * Description: registers dependecies for plugins and checks if they were saved + * Expected: registered dependecies should be returned from database + */ +RUNNER_TEST(plugin_dao_test_register_library_dependencies) +{ + { + std::string libraryPath("np4 lib_path"); + std::string libraryName("np4"); + + PluginMetafileData pluginData; + pluginData.m_libraryName = libraryName; + + PluginHandle handle = + PluginDAO::registerPlugin(pluginData, libraryPath); + PluginDAO::setPluginInstallationStatus( + handle, + PluginDAO:: + INSTALLATION_COMPLETED); + RUNNER_ASSERT(PluginDAO::isPluginInstalled(libraryName) == true); + + PluginHandle depHandles[] = { 117, 119 }; + + PluginHandleSetPtr dependencies(new PluginHandleSet); + dependencies->insert(depHandles[0]); + dependencies->insert(depHandles[1]); + + PluginDAO::registerPluginLibrariesDependencies(handle, dependencies); + + PluginDAO dao(handle); + PluginHandleSetPtr retDependencies; + retDependencies = dao.getLibraryDependencies(); + + RUNNER_ASSERT( + retDependencies->size() == sizeof(depHandles) / + sizeof(depHandles[0])); + RUNNER_ASSERT( + retDependencies->find(depHandles[0]) != retDependencies->end()); + RUNNER_ASSERT( + retDependencies->find(depHandles[1]) != retDependencies->end()); + } +} + +/* + * Name: plugin_dao_test_register_required_object + * Description: registers required plugin objects for plugins and checks if they + * were saved + * Expected: registered required plugin objects should be returned from database + */ +RUNNER_TEST(plugin_dao_test_register_required_object) +{ + { + std::string libraryPath("np5 lib_path"); + std::string libraryName("np5"); + + PluginMetafileData pluginData; + pluginData.m_libraryName = libraryName; + + PluginHandle handle = + PluginDAO::registerPlugin(pluginData, libraryPath); + PluginDAO::setPluginInstallationStatus( + handle, + PluginDAO:: + INSTALLATION_COMPLETED); + RUNNER_ASSERT(PluginDAO::isPluginInstalled(libraryName) == true); + + const size_t numObjects = 2; + std::string objectReq[numObjects]; + objectReq[0] = std::string("object1.req"); + objectReq[1] = std::string("object2.req"); + PluginDAO::registerPluginRequiredObject(objectReq[0], handle); + PluginDAO::registerPluginRequiredObject(objectReq[1], handle); + + WrtDB::PluginObjectsDAO::ObjectsPtr objects = + PluginDAO::getRequiredObjectsForPluginHandle(handle); + + RUNNER_ASSERT(objects->size() == numObjects + && objects->find(objectReq[0]) != objects->end() + && objects->find(objectReq[1]) != objects->end()); + } +} + +/* + * Name: plugin_dao_test_is_library_installed + * Description: tests if plugin isntallation/registrartion works + * Expected: only registered plugins should be reported as installed + */ +RUNNER_TEST(plugin_dao_test_is_library_installed) +{ + { + //exist + std::list preinstalled; + preinstalled.push_back("plugin1"); + preinstalled.push_back("plugin2"); + preinstalled.push_back("plugin3"); + preinstalled.push_back("p4"); + preinstalled.push_back("p5"); + + FOREACH(it, preinstalled) + RUNNER_ASSERT_MSG(PluginDAO::isPluginInstalled(*it), + std::string("Not found: ") + *it); + } + + { + //does not exist + RUNNER_ASSERT_MSG( + PluginDAO::isPluginInstalled("not_installed1") == false, + "Found not_installed1"); + RUNNER_ASSERT_MSG(PluginDAO::isPluginInstalled("p 4") == false, + "Found p 4"); + RUNNER_ASSERT_MSG(PluginDAO::isPluginInstalled("") == false, + "Found "); + RUNNER_ASSERT_MSG(PluginDAO::isPluginInstalled("p33") == false, + "Found p33"); + RUNNER_ASSERT_MSG(PluginDAO::isPluginInstalled("feature1") == false, + "Found feature1"); + } +} + +/* + * Name: plugin_dao_test_get_plugin_handle_list + * Description: test of returning plugin handle list + * Expected: returned list should be no less than number of registered plugins + */ +RUNNER_TEST(plugin_dao_test_get_plugin_handle_list) +{ + PluginHandleList handles = PluginDAO::getPluginHandleList(); + RUNNER_ASSERT(handles.size() >= 5); +} + +/* + * Name: plugin_dao_test_constructor_name + * Description: tests construction of plugin dao based on plugin name + * Expected: Instance of dao should be constructed only + * if there is given plugin in database + */ +RUNNER_TEST(plugin_dao_test_constructor_name) +{ + { + //exist + std::list preinstalled; + preinstalled.push_back("plugin1"); + preinstalled.push_back("plugin2"); + preinstalled.push_back("plugin3"); + preinstalled.push_back("p4"); + preinstalled.push_back("p5"); + + FOREACH(it, preinstalled) + { + PluginDAO dao(*it); + RUNNER_ASSERT_WHAT_EQUALS(dao.getLibraryName(), *it); + } + } + + { + //does not exist + std::list not_installed; + not_installed.push_back("plugin 1"); + not_installed.push_back(""); + not_installed.push_back("p 3"); + + FOREACH(it, not_installed) + { + Try { + //Plugin not exist + PluginDAO dao(*it); + RUNNER_ASSERT_MSG(false, "should not be found"); + } + Catch(PluginDAO::Exception::PluginNotExist) { + continue; + } + } + } +} + +/* + * Name: plugin_dao_test_get_plugin_properties + * Description: tests reading plugin properties from database + * Expected: Data, inserted into database, should be accessible via dao + */ +RUNNER_TEST(plugin_dao_test_get_plugin_properties) +{ + { + PluginDAO dao("p4"); + RUNNER_ASSERT(dao.getPluginHandle() == 4); + RUNNER_ASSERT_WHAT_EQUALS(dao.getLibraryName(), "p4"); + RUNNER_ASSERT_WHAT_EQUALS(dao.getLibraryPath(), "path_to_p4"); + } + + { + PluginDAO dao(5); + RUNNER_ASSERT(dao.getPluginHandle() == 5); + RUNNER_ASSERT_WHAT_EQUALS(dao.getLibraryName(), "p5"); + RUNNER_ASSERT_WHAT_EQUALS(dao.getLibraryPath(), "path_to_p5"); + } + + { + PluginDAO dao(2); + RUNNER_ASSERT(dao.getPluginHandle() == 2); + RUNNER_ASSERT_WHAT_EQUALS(dao.getLibraryName(), "plugin2"); + RUNNER_ASSERT_WHAT_EQUALS(dao.getLibraryPath(), "path_to_plugin2"); + } + + { + PluginDAO dao(1); + RUNNER_ASSERT(dao.getPluginHandle() == 1); + RUNNER_ASSERT_WHAT_EQUALS(dao.getLibraryName(), "plugin1"); + RUNNER_ASSERT_WHAT_EQUALS(dao.getLibraryPath(), ""); + } +} + +/* + * Name: plugin_dao_test_get_implemented_objects_for_plugin_handle_1 + * Description: tests receiving from dao Implemented Objects + * Expected: returned object is size 0 + */ +RUNNER_TEST(plugin_dao_test_get_implemented_objects_for_plugin_handle_1) +{ + { + const int handle = 1; + PluginDAOReadOnly dao(handle); + auto dbHandle = dao.getPluginHandle(); + RUNNER_ASSERT(dbHandle == handle); + auto objects = dao.getImplementedObjectsForPluginHandle(dbHandle); + + RUNNER_ASSERT(objects.empty()); + } +} + +/* + * Name: plugin_dao_test_get_implemented_objects_for_plugin_handle_2 + * Description: tests receiving from dao Implemented Objects + * Expected: returned object is size as it was inserted + */ +RUNNER_TEST(plugin_dao_test_get_implemented_objects_for_plugin_handle_2) +{ + { + std::set< std::string > preinstalled = { + "" + }; + + PluginDAOReadOnly dao(2); + auto dbHandle = dao.getPluginHandle(); + auto objects = dao.getImplementedObjectsForPluginHandle(dbHandle); + + //LogError("\n" << objects.size() << " " << preinstalled.size() << + // "\n"); + + RUNNER_ASSERT(objects.size() == preinstalled.size()); + + FOREACH(dbObject, objects) + { + RUNNER_ASSERT(preinstalled.find(*dbObject) != preinstalled.end()); + } + } +} + +/* + * Name: plugin_dao_test_get_implemented_objects_for_plugin_handle_3 + * Description: tests receiving from dao Implemented Objects + * Expected: returned objects list has preinserted object + */ +RUNNER_TEST(plugin_dao_test_get_implemented_objects_for_plugin_handle_3) +{ + { + std::set< std::string > preinstalled = { + "Plugin_3_Object_A" + }; + + PluginDAOReadOnly dao(3); + auto dbHandle = dao.getPluginHandle(); + auto objects = dao.getImplementedObjectsForPluginHandle(dbHandle); + RUNNER_ASSERT(objects.size() == preinstalled.size()); + + FOREACH(dbObject, objects) + { + RUNNER_ASSERT(preinstalled.find(*dbObject) != preinstalled.end()); + } + } +} + +/* + * Name: plugin_dao_test_get_implemented_objects_for_plugin_handle_4 + * Description: tests receiving from dao Implemented Objects + * Expected: returned objects list has all preinserted objects + */ +RUNNER_TEST(plugin_dao_test_get_implemented_objects_for_plugin_handle_4) +{ + { + std::set< std::string > preinstalled = { + "Plugin_4_Object_A", + "Plugin_4_Object_B", + "Plugin_4_Object_C", + }; + + PluginDAOReadOnly dao(4); + auto dbHandle = dao.getPluginHandle(); + auto objects = dao.getImplementedObjectsForPluginHandle(dbHandle); + RUNNER_ASSERT(objects.size() == preinstalled.size()); + + FOREACH(dbObject, objects) + { + RUNNER_ASSERT(preinstalled.find(*dbObject) != preinstalled.end()); + } + } +} + +/* + * Name: plugin_dao_test_get_implemented_objects_for_plugin_handle_5 + * Description: tests receiving from dao Implemented Objects + * Expected: returned objects list do not have object that was not inserted + */ +RUNNER_TEST(plugin_dao_test_get_implemented_objects_for_plugin_handle_5) +{ + { + std::set< std::string > preinstalled = { + "Plugin_5_Object_B", + }; + + PluginDAOReadOnly dao(5); + auto dbHandle = dao.getPluginHandle(); + auto objects = dao.getImplementedObjectsForPluginHandle(dbHandle); + RUNNER_ASSERT(objects.size() == preinstalled.size()); + + FOREACH(dbObject, objects) + { + RUNNER_ASSERT(preinstalled.find(*dbObject) == preinstalled.end()); + } + } +} + +#undef RUNNER_ASSERT_WHAT_EQUALS diff --git a/tests/dao/TestCases_PropertyDAO.cpp b/tests/dao/TestCases_PropertyDAO.cpp new file mode 100644 index 0000000..8ff2ad6 --- /dev/null +++ b/tests/dao/TestCases_PropertyDAO.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file TestCases_PropertyDAO.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains tests for property dao class. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace WrtDB; +using namespace WrtDB::PropertyDAOReadOnly; + +// Widgets used "tizenid201", "tizenid202", "tizenid203", 2003(saved by +// wrt_dao_tests_prepare_db.sh) + +#define RUNNER_ASSERT_WHAT_EQUALS(in, test) \ + { std::string tmp(in); \ + RUNNER_ASSERT_MSG(tmp == test, "Equals: [" + tmp + "]"); } + +#define RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(in, test) \ + { \ + if (in.IsNull()) { RUNNER_ASSERT_MSG(false, "NULL"); } \ + else { RUNNER_ASSERT_WHAT_EQUALS(DPL::ToUTF8String(*in), test); } \ + } + +RUNNER_TEST_GROUP_INIT(DAO) + + +/* + * Name: property_dao_get_lists + * Description: tests returning list of properties for given id + * Expected: data received should match those, which were inserted in prepare + * script + */ +RUNNER_TEST(property_dao_get_lists) +{ + { //property list + struct three_field{ + WrtDB::TizenAppId tappid; + DbWidgetHandle whandleid; + size_t nrow; + }; + + three_field f3; + std::list prefList; + std::list::iterator it; + + f3.tappid=L"tizenid201";f3.whandleid=2000;f3.nrow=2; + prefList.push_back(f3); + f3.tappid=L"tizenid202"; f3.whandleid=2001;f3.nrow=1; + prefList.push_back(f3); + f3.tappid=L"tizenid203"; f3.whandleid=2002;f3.nrow=2; + prefList.push_back(f3); + f3.tappid=L"tizenid204"; f3.whandleid=2003;f3.nrow=0; + prefList.push_back(f3); + + for(it=prefList.begin();it!=prefList.end();++it) + { + PropertyDAOReadOnly::WidgetPreferenceList prefs_tid = + PropertyDAOReadOnly::GetPropertyList(it->tappid); + RUNNER_ASSERT(prefs_tid.size() == it->nrow); + } + } + { //property key list + WidgetPropertyKeyList orig_2000; + orig_2000.push_back(DPL::FromUTF8String("key1_for_2000")); + orig_2000.push_back(DPL::FromUTF8String("key2_for_2000")); + + WidgetPropertyKeyList orig_2001; + orig_2001.push_back(DPL::FromUTF8String("key1_for_2001")); + + WidgetPropertyKeyList orig_2002; + orig_2002.push_back(DPL::FromUTF8String("key1_for_2002")); + orig_2002.push_back(DPL::FromUTF8String("key2_for_2002")); + + std::map prefsKeyMap; + prefsKeyMap.insert(std::pair( + L"tizenid201", &orig_2000)); + prefsKeyMap.insert(std::pair( + L"tizenid202", &orig_2001)); + prefsKeyMap.insert(std::pair( + L"tizenid203", &orig_2002)); + + FOREACH(it_out, prefsKeyMap) { + WidgetPropertyKeyList got = PropertyDAOReadOnly::GetPropertyKeyList( + it_out->first); + RUNNER_ASSERT(got.size() == it_out->second->size()); + //TODO + // FOREACH(it_in, got) + // { + // RUNNER_ASSERT(it_out->second. + // } + } + } +} + + +/* + * Name: property_dao_get_list_exceptions + * Description: tests returning exception for given tizen_appid if is + * not inserted into WidgetInfo table + * Expected: procedure passes when is exception. Widget absent in the WidgetInfo + * table. + */ +RUNNER_TEST(property_dao_get_list_exceptions) +{ + { + bool assert_flag; + WrtDB::TizenAppId app_id_non_exists = L"non_exists"; + + assert_flag=true; + Try{ + PropertyDAOReadOnly::WidgetPreferenceList prefs = + PropertyDAOReadOnly::GetPropertyList(app_id_non_exists); + } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) + { + assert_flag=false; + } + RUNNER_ASSERT_MSG(!(assert_flag),"Error, value doesn't make exception"); + } +} + + +/* + * Name: property_dao_set_update_remove + * Description: tests set new property for widget, updating property and + * removing it + * Expected: given operation should works + */ +RUNNER_TEST(property_dao_set_update_remove) +{ + WidgetPropertyKeyList keys = PropertyDAOReadOnly::GetPropertyKeyList( + L"tizenid201"); + + //ADD + PropertyDAO::SetProperty(L"tizenid201", + DPL::FromUTF8String("new_key"), + DPL::FromUTF8String("new_value1")); + + RUNNER_ASSERT_MSG( + keys.size() + 1 == + PropertyDAOReadOnly::GetPropertyKeyList(L"tizenid201").size(), + "new property not added"); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL( + PropertyDAOReadOnly::GetPropertyValue(L"tizenid201", + DPL::FromUTF8String("new_key")), + "new_value1"); + + //UPDATE + PropertyDAO::SetProperty(L"tizenid201", + DPL::FromUTF8String("new_key"), + DPL::FromUTF8String("new_value2")); + RUNNER_ASSERT_MSG( + keys.size() + 1 == + PropertyDAOReadOnly::GetPropertyKeyList(L"tizenid201").size(), + "new property not added"); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL( + PropertyDAOReadOnly::GetPropertyValue(L"tizenid201", + DPL::FromUTF8String("new_key")), + "new_value2"); + + //REMOVE + PropertyDAO::RemoveProperty(L"tizenid201", DPL::FromUTF8String("new_key")); + + RUNNER_ASSERT_MSG( + keys.size() == PropertyDAOReadOnly::GetPropertyKeyList( + L"tizenid201").size(), + "property not removed"); +} + +/* + * Name: property_dao_get_value + * Description: tests if properties can be received from database + * Expected: value, which were inserted before test, should be present + */ +RUNNER_TEST(property_dao_get_value) +{ + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL( + PropertyDAOReadOnly::GetPropertyValue( + L"tizenid201", DPL::FromUTF8String("key1_for_2000")), + "value_for_key1_2000"); + + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL( + PropertyDAOReadOnly::GetPropertyValue( + L"tizenid201", DPL::FromUTF8String("key2_for_2000")), + "value_for_key2_2000"); +} + +#undef RUNNER_ASSERT_WHAT_EQUALS diff --git a/tests/dao/TestCases_SecurityOriginDAO.cpp b/tests/dao/TestCases_SecurityOriginDAO.cpp new file mode 100644 index 0000000..fc4e46e --- /dev/null +++ b/tests/dao/TestCases_SecurityOriginDAO.cpp @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file TestCases_SecurityOriginDAO.cpp + * @author Slawomir Pajak (s.pajak@partner.samsung.com) + * @version 1.0 + * @brief This file contains tests for security origin dao class. + */ + +#include +#include + + +RUNNER_TEST_GROUP_INIT(DAO) + +using namespace SecurityOriginDB; + +namespace { + +class SecurityOriginDAOWrapper { +public: + static SecurityOriginDAO* getSecurityOriginDAO() + { + static SecurityOriginDAOPtr securityOriginDAO( + new SecurityOriginDB::SecurityOriginDAO(DPL::FromASCIIString("testWidget123"))); + return securityOriginDAO.get(); + } +}; +} + +/** + * Name: security_origin_dao_set_remove + * Description: Test saves SecurityOriginData object, reads it, and removes it at the end. + * Expected: All operations should succeed. + */ +RUNNER_TEST(security_origin_dao_set_remove) +{ + SecurityOriginDAO* securityOriginDAO = SecurityOriginDAOWrapper::getSecurityOriginDAO(); + + SecurityOriginDataList dataList = securityOriginDAO->getSecurityOriginDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "SecurityOriginDataList should be empty"); + + Origin origin(L"scheme", L"host", 123); + SecurityOriginData securityData(WrtDB::FEATURE_WEB_NOTIFICATION, origin); + securityOriginDAO->setSecurityOriginData(securityData, RESULT_ALLOW_ONCE, false); + + Origin origin2(L"scheme2", L"host2", 1234); + SecurityOriginData securityData2(WrtDB::FEATURE_GEOLOCATION, origin2); + securityOriginDAO->setSecurityOriginData(securityData2, RESULT_DENY_ONCE, true); + + dataList = securityOriginDAO->getSecurityOriginDataList(); + + RUNNER_ASSERT_MSG(dataList.size() == 2, "CertificateDataList should not be empty"); + + securityOriginDAO->removeSecurityOriginData(securityData); + securityOriginDAO->removeSecurityOriginData(securityData2); + + dataList = securityOriginDAO->getSecurityOriginDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "SecurityOriginDataList should be empty"); +} + +/** + * Name: security_origin_dao_update + * Description: Test checks update operation for SecurityOriginData. + * Expected: All operations should succeed. + */ +RUNNER_TEST(security_origin_dao_update) +{ + SecurityOriginDAO* securityOriginDAO = SecurityOriginDAOWrapper::getSecurityOriginDAO(); + + SecurityOriginDataList dataList = securityOriginDAO->getSecurityOriginDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "SecurityOriginDataList should be empty"); + + Origin origin(L"scheme", L"host", 123); + SecurityOriginData securityData(WrtDB::FEATURE_WEB_NOTIFICATION, origin); + securityOriginDAO->setSecurityOriginData(securityData, RESULT_ALLOW_ONCE, true); + + dataList = securityOriginDAO->getSecurityOriginDataList(); + RUNNER_ASSERT_MSG(dataList.size() == 1, "CertificateDataList should not be empty"); + RUNNER_ASSERT((*dataList.begin())->feature == WrtDB::FEATURE_WEB_NOTIFICATION); + RUNNER_ASSERT((*dataList.begin())->origin.host == L"host"); + RUNNER_ASSERT((*dataList.begin())->origin.scheme == L"scheme"); + RUNNER_ASSERT((*dataList.begin())->origin.port == 123); + RUNNER_ASSERT(securityOriginDAO->getResult(**dataList.begin()) == RESULT_ALLOW_ONCE); + RUNNER_ASSERT(securityOriginDAO->isReadOnly(**dataList.begin())); + + securityOriginDAO->setSecurityOriginData(securityData, RESULT_DENY_ONCE, false); + + dataList = securityOriginDAO->getSecurityOriginDataList(); + RUNNER_ASSERT_MSG(dataList.size() == 1, "CertificateDataList should not be empty"); + RUNNER_ASSERT((*dataList.begin())->feature == WrtDB::FEATURE_WEB_NOTIFICATION); + RUNNER_ASSERT((*dataList.begin())->origin.host == L"host"); + RUNNER_ASSERT((*dataList.begin())->origin.scheme == L"scheme"); + RUNNER_ASSERT((*dataList.begin())->origin.port == 123); + RUNNER_ASSERT(securityOriginDAO->getResult(**dataList.begin()) == RESULT_DENY_ONCE); + RUNNER_ASSERT(!securityOriginDAO->isReadOnly(**dataList.begin())); + + securityOriginDAO->removeSecurityOriginData(securityData); + + dataList = securityOriginDAO->getSecurityOriginDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "SecurityOriginDataList should be empty"); +} + + +/** + * Name: security_origin_dao_remove_by_result + * Description: Test remove by result operation for SecurityOriginData. + * Expected: All operations should succeed. + */ +RUNNER_TEST(security_origin_dao_remove_by_result) +{ + SecurityOriginDAO* securityOriginDAO = SecurityOriginDAOWrapper::getSecurityOriginDAO(); + + SecurityOriginDataList dataList = securityOriginDAO->getSecurityOriginDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "SecurityOriginDataList should be empty"); + + Origin origin(L"scheme", L"host", 123); + SecurityOriginData securityData(WrtDB::FEATURE_WEB_NOTIFICATION, origin); + securityOriginDAO->setSecurityOriginData(securityData, RESULT_ALLOW_ONCE, false); + + Origin origin2(L"scheme2", L"host2", 1234); + SecurityOriginData securityData2(WrtDB::FEATURE_GEOLOCATION, origin2); + securityOriginDAO->setSecurityOriginData(securityData2, RESULT_DENY_ONCE, true); + + Origin origin3(L"scheme3", L"host3", 2546); + SecurityOriginData securityData3(WrtDB::FEATURE_FULLSCREEN_MODE, origin3); + securityOriginDAO->setSecurityOriginData(securityData3, RESULT_DENY_ONCE, false); + + dataList = securityOriginDAO->getSecurityOriginDataList(); + RUNNER_ASSERT_MSG(dataList.size() == 3, "CertificateDataList should not be empty"); + + securityOriginDAO->removeSecurityOriginData(RESULT_DENY_ONCE); + + dataList = securityOriginDAO->getSecurityOriginDataList(); + RUNNER_ASSERT_MSG(dataList.size() == 1, "CertificateDataList should not be empty"); + + securityOriginDAO->removeSecurityOriginData(RESULT_ALLOW_ONCE); + + dataList = securityOriginDAO->getSecurityOriginDataList(); + RUNNER_ASSERT_MSG(dataList.empty(), "SecurityOriginDataList should be empty"); +} + +/** + * Name: security_origin_dao_origin_operators + * Description: Test comparison operators for Origin class. + * Expected: All operations should succeed. + */ +RUNNER_TEST(security_origin_dao_origin_operators) +{ + Origin origin1(L"scheme", L"host", 123); + Origin origin2(L"scheme", L"host", 123); + Origin origin3(L"scheme1", L"host", 123); + Origin origin4(L"scheme", L"host2", 123); + Origin origin5(L"scheme", L"host", 122); + + RUNNER_ASSERT(origin1 == origin2); + RUNNER_ASSERT(origin2 == origin1); + RUNNER_ASSERT(origin1 != origin3); + RUNNER_ASSERT(origin1 != origin4); + RUNNER_ASSERT(origin1 != origin5); + RUNNER_ASSERT(origin3 != origin4); + RUNNER_ASSERT(origin4 != origin5); +} + +/** + * Name: security_origin_dao_data_operators + * Description: Test comparison operators for SecurityOriginData class. + * Expected: All operations should succeed. + */ +RUNNER_TEST(security_origin_dao_data_operators) +{ + SecurityOriginData data1(WrtDB::FEATURE_WEB_NOTIFICATION, Origin(L"scheme", L"host", 123)); + SecurityOriginData data2(WrtDB::FEATURE_WEB_NOTIFICATION, Origin(L"scheme", L"host", 123)); + SecurityOriginData data3(WrtDB::FEATURE_END, Origin(L"scheme", L"host", 123)); + SecurityOriginData data4(WrtDB::FEATURE_WEB_NOTIFICATION, Origin(L"scheme1", L"host", 123)); + SecurityOriginData data5(WrtDB::FEATURE_WEB_NOTIFICATION, Origin(L"scheme", L"host1", 123)); + SecurityOriginData data6(WrtDB::FEATURE_WEB_NOTIFICATION, Origin(L"scheme", L"host", 124)); + + RUNNER_ASSERT(data1 == data2); + RUNNER_ASSERT(data2 == data1); + RUNNER_ASSERT(data1 != data3); + RUNNER_ASSERT(data1 != data4); + RUNNER_ASSERT(data1 != data5); + RUNNER_ASSERT(data1 != data6); + RUNNER_ASSERT(data3 != data4); + RUNNER_ASSERT(data3 != data5); + RUNNER_ASSERT(data3 != data6); + RUNNER_ASSERT(data4 != data5); + RUNNER_ASSERT(data4 != data6); + RUNNER_ASSERT(data5 != data6); +} diff --git a/tests/dao/TestCases_WidgetDAO.cpp b/tests/dao/TestCases_WidgetDAO.cpp new file mode 100644 index 0000000..806ee1e --- /dev/null +++ b/tests/dao/TestCases_WidgetDAO.cpp @@ -0,0 +1,1636 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file TestCases_WidgetDAO.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains tests for widget dao class. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace WrtDB; + +namespace { +class WacSecurityMock : public WrtDB::IWidgetSecurity +{ + public: + WacSecurityMock() : + mRecognized(false), + mDistributorSigned(false) + {} + + virtual const WidgetCertificateDataList& getCertificateList() const + { + return mList; + } + + virtual bool isRecognized() const + { + return mRecognized; + } + virtual bool isDistributorSigned() const + { + return mDistributorSigned; + } + virtual void getCertificateChainList(CertificateChainList& /*lst*/) const {} + virtual void getCertificateChainList(CertificateChainList& /*lst*/, + CertificateSource /*source*/) const {} + + WrtDB::WidgetCertificateDataList& getCertificateListRef() + { + return mList; + } + + void setRecognized(bool recognized) + { + mRecognized = recognized; + } + void setDistributorSigned(bool distributorSigned) + { + mDistributorSigned = distributorSigned; + } + + private: + WrtDB::WidgetCertificateDataList mList; + // author signature verified + bool mRecognized; + // known distribuor + bool mDistributorSigned; + // distributor is wac +}; + +TizenAppId _registerWidget(const WidgetRegisterInfo& regInfo, + const IWidgetSecurity& sec, + int line) +{ + TizenAppId tizenAppId; + Try { + auto previous = WidgetDAO::getTizenAppidList(); + + // register widget + tizenAppId = WidgetDAO::registerWidgetGeneratePkgId(regInfo, sec); + + RUNNER_ASSERT_MSG(!tizenAppId.empty(), + "(called from line " << line << ")"); + + auto current = WidgetDAO::getTizenAppidList(); + RUNNER_ASSERT_MSG(previous.size() + 1 == current.size(), + "(called from line " << line << ")"); + + RUNNER_ASSERT_MSG(WidgetDAO::isWidgetInstalled( + tizenAppId), + "(called from line " << line << " tizenAppId: " << + tizenAppId << ")"); + } + Catch(WidgetDAO::Exception::AlreadyRegistered) { + RUNNER_ASSERT_MSG( + false, + "Unexpected exception (called from line " << line << ")"); + } + return tizenAppId; +} + +#define REGISTER_WIDGET(regInfo, sec) _registerWidget((regInfo), \ + (sec), \ + __LINE__) + +template +bool checkException(Function fun) +{ + Try + { + fun(); + } + Catch(Exception){ + return true; + } + return false; +} + +} // namespace + +// Widgets used <2300,2500), 2000, 2001, 2002, 2003 + +#define RUNNER_ASSERT_WHAT_EQUALS(in, test) \ + { std::string tmp(in); \ + RUNNER_ASSERT_MSG(tmp == test, "Equals: [" + tmp + "]"); } + +#define RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(in, test) \ + { \ + if (in.IsNull()) { RUNNER_ASSERT_MSG(false, "NULL"); } \ + else { RUNNER_ASSERT_WHAT_EQUALS(DPL::ToUTF8String(*in), test); } \ + } + +#define RUNNER_ASSERT_WHAT_EQUALS_OPTIONALINT(in, test) \ + { \ + if (in.IsNull()) { RUNNER_ASSERT_MSG(false, "NULL"); } \ + else { RUNNER_ASSERT_MSG(*in == test, "Equals: [" + *in + "]"); } \ + } + +#define RUNNER_ASSERT_EXCEPTION(exceptionType, function) \ + { \ + RUNNER_ASSERT(checkException([](){function})); \ + } + +RUNNER_TEST_GROUP_INIT(DAO) + +//2300 +/* + * Name: widget_dao_test_register_widget_empty_strings + * Description: Tests registeration of new widget with empty values + * Expected: widget should be registered in database + */ +RUNNER_TEST(widget_dao_test_register_widget_empty_strings) +{ + WidgetRegisterInfo regInfo; + + //info + regInfo.configInfo.widget_id = DPL::FromUTF8String(""); + regInfo.configInfo.version = DPL::FromUTF8String(""); + regInfo.configInfo.width = 10; + regInfo.configInfo.height = 10; + regInfo.configInfo.authorName = DPL::FromUTF8String(""); + regInfo.configInfo.authorEmail = DPL::FromUTF8String(""); + regInfo.configInfo.authorHref = DPL::FromUTF8String(""); + regInfo.baseFolder = ""; + //TODO authenticated, etc... + regInfo.configInfo.flashNeeded = false; + regInfo.configInfo.minVersionRequired = DPL::FromUTF8String("1.0"); + regInfo.configInfo.backSupported = true; + + //loc info + ConfigParserData::LocalizedData locData; + locData.name = DPL::FromUTF8String(""); + locData.shortName = DPL::FromUTF8String(""); + locData.description = DPL::FromUTF8String(""); + locData.license = DPL::FromUTF8String(""); + locData.licenseFile = DPL::FromUTF8String(""); + locData.licenseHref = DPL::FromUTF8String(""); + regInfo.configInfo.localizedDataSet.insert( + std::make_pair(DPL::FromUTF8String("en"), locData)); + + //userAgentLoc + + //icons + ConfigParserData::Icon icon(DPL::FromUTF8String("")); + icon.width = 10; + icon.height = 10; + LocaleSet locs; + locs.insert(DPL::FromUTF8String("en")); + WidgetRegisterInfo::LocalizedIcon locIcon(icon, locs); + regInfo.localizationData.icons.push_back(locIcon); + + //start file + WidgetRegisterInfo::StartFileProperties prop; + prop.encoding = DPL::FromUTF8String(""); + prop.type = DPL::FromUTF8String(""); + WidgetRegisterInfo::LocalizedStartFile file; + file.path = DPL::FromUTF8String(""); + file.propertiesForLocales.insert( + std::make_pair(DPL::FromUTF8String("en"), prop)); + regInfo.localizationData.startFiles.push_back(file); + + //widget pref + ConfigParserData::Preference pref(DPL::FromUTF8String(""), false); + pref.value = DPL::FromUTF8String(""); + regInfo.configInfo.preferencesList.insert(pref); + + //widget feature + ConfigParserData::Feature feat(DPL::FromUTF8String("")); + regInfo.configInfo.featuresList.insert(feat); + + //win modes + regInfo.configInfo.windowModes.insert(DPL::FromUTF8String("")); + + //WARP info + ConfigParserData::AccessInfo access(DPL::FromUTF8String(""), true); + regInfo.configInfo.accessInfoSet.insert(access); + + //certificates + WidgetCertificateData cert; + cert.owner = WidgetCertificateData::AUTHOR; + cert.type = WidgetCertificateData::ROOT; + cert.chainId = 1; + cert.strMD5Fingerprint = ""; + cert.strSHA1Fingerprint = ""; + cert.strCommonName = DPL::FromUTF8String(""); + + WacSecurityMock security; + security.getCertificateListRef().push_back(cert); + + REGISTER_WIDGET(regInfo, security); +} + +/* + * Name: widget_dao_test_register_widget_empty_strings + * Description: Tests possiblity of registering twice same content (different + * tizenId) + * Expected: it should be possible + */ +RUNNER_TEST(widget_dao_test_twice_install_same_widget) +{ + WacSecurityMock sec; + { + WidgetRegisterInfo regInfo; + REGISTER_WIDGET(regInfo, sec); + } + { + WidgetRegisterInfo regInfo; + REGISTER_WIDGET(regInfo, sec); + } +} + +/* + * Name: widget_dao_test_register_widget_minimum_info + * Description: Tests simplest registeration of new widget + * Expected: widget should be registered in database + */ +RUNNER_TEST(widget_dao_test_register_widget_minimum_info) +{ + WacSecurityMock sec; + const std::size_t NUMBER_OF_WIDGETS = 5; + + TizenAppId lastTizenAppId; + + for (std::size_t number = 0; number < NUMBER_OF_WIDGETS; ++number) { + WidgetRegisterInfo regInfo; + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + lastTizenAppId = tizenAppId; + + WidgetDAO dao(tizenAppId); + //TODO check nulls + } +} + +/* + * Name: widget_dao_test_register_widget_info + * Description: Tests registeration of many widgets + * Expected: all widgets should be registered in database + */ +RUNNER_TEST(widget_dao_test_register_widget_info) +{ + WacSecurityMock sec; + const std::size_t NUMBER_OF_WIDGETS = 5; + + for (std::size_t number = 0; number < NUMBER_OF_WIDGETS; ++number) { + std::ostringstream str; + str << "register_info_test_" << number; + + WidgetRegisterInfo regInfo; + regInfo.configInfo.widget_id = DPL::FromUTF8String(str.str()); + regInfo.configInfo.version = DPL::FromUTF8String(str.str()); + regInfo.configInfo.width = 10; + regInfo.configInfo.height = 10; + regInfo.configInfo.authorName = DPL::FromUTF8String(str.str()); + regInfo.configInfo.authorEmail = DPL::FromUTF8String(str.str()); + regInfo.configInfo.authorHref = DPL::FromUTF8String(str.str()); + regInfo.baseFolder = str.str(); //base folder at the end has / + regInfo.configInfo.flashNeeded = false; + //TODO authenticated, etc... + //in wrt-installer: TaskWidgetConfig::fillWidgetConfig: + //regInfo.minVersion = regInfo.configInfo.minVersionRequired + regInfo.minVersion = DPL::FromUTF8String("1.0"); + regInfo.configInfo.backSupported = true; + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO dao(tizenAppId); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getGUID(), str.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getVersion(), str.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getAuthorName(), str.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getAuthorEmail(), str.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getAuthorHref(), str.str()); + RUNNER_ASSERT_WHAT_EQUALS(dao.getBaseFolder(), str.str() + "/"); + RUNNER_ASSERT(dao.getWebkitPluginsRequired() == false); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getMinimumWacVersion(), "1.0"); + } +} + +/* + * Name: widget_dao_test_register_widget_extended_info + * Description: Tests registeration of widget_extended_info + * Expected: registeration of extended inforamtion is checked + * via existence of backgroudn page value + */ +RUNNER_TEST(widget_dao_test_register_widget_extended_info) +{ + WacSecurityMock sec; + const std::size_t NUMBER_OF_WIDGETS = 5; + + for (std::size_t number = 0; number < NUMBER_OF_WIDGETS; ++number) { + std::ostringstream str; + str << "register_ext_info_test_" << number; + + WidgetRegisterInfo regInfo; + + regInfo.configInfo.backgroundPage = L"background.html"; + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO dao(tizenAppId); + + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getBackgroundPage(), + "background.html"); + } +} + +/* + * Name: widget_dao_test_register_widget_localized_info + * Description: Tests registeration of localized widgets information + * Expected: values received by dao should match those which were registered + */ +RUNNER_TEST(widget_dao_test_register_widget_localized_info) +{ + WacSecurityMock sec; + const std::size_t NUMBER_OF_WIDGETS = 5; + + for (std::size_t number = 0; number < NUMBER_OF_WIDGETS; ++number) { + WidgetRegisterInfo regInfo; + std::ostringstream str_en; + std::ostringstream str_pl; + str_en << "register_loc_info_test_en_" << number; + str_pl << "register_loc_info_test_pl_" << number; + { //EN + ConfigParserData::LocalizedData locDataEn; + locDataEn.name = DPL::FromUTF8String(str_en.str()); + locDataEn.shortName = DPL::FromUTF8String(str_en.str()); + locDataEn.description = DPL::FromUTF8String(str_en.str()); + locDataEn.license = DPL::FromUTF8String(str_en.str()); + locDataEn.licenseFile = DPL::FromUTF8String(str_en.str()); + locDataEn.licenseHref = DPL::FromUTF8String(str_en.str()); + regInfo.configInfo.localizedDataSet.insert( + std::make_pair(DPL::FromUTF8String("en"), locDataEn)); + } + + { //PL + ConfigParserData::LocalizedData locDataPl; + locDataPl.name = DPL::FromUTF8String(str_pl.str()); + locDataPl.shortName = DPL::FromUTF8String(str_pl.str()); + locDataPl.description = DPL::FromUTF8String(str_pl.str()); + locDataPl.license = DPL::FromUTF8String(str_pl.str()); + locDataPl.licenseFile = DPL::FromUTF8String(str_pl.str()); + locDataPl.licenseHref = DPL::FromUTF8String(str_pl.str()); + regInfo.configInfo.localizedDataSet.insert( + std::make_pair(DPL::FromUTF8String("pl"), locDataPl)); + } + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO dao(tizenAppId); + RUNNER_ASSERT_MSG(dao.getLanguageTags().size() == 2, + "language tags list invalid"); + + { //EN + WidgetLocalizedInfo locInfo = + dao.getLocalizedInfo(DPL::FromUTF8String("en")); + + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(locInfo.name, + str_en.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(locInfo.shortName, + str_en.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(locInfo.description, + str_en.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(locInfo.license, + str_en.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(locInfo.licenseHref, + str_en.str()); + } + + { //PL + WidgetLocalizedInfo locInfo = + dao.getLocalizedInfo(DPL::FromUTF8String("pl")); + + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(locInfo.name, + str_pl.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(locInfo.shortName, + str_pl.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(locInfo.description, + str_pl.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(locInfo.license, + str_pl.str()); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(locInfo.licenseHref, + str_pl.str()); + } + } +} + +/* + * Name: widget_dao_test_register_widget_icons + * Description: Tests registeration of localized icons information + * Expected: values received by dao should match those which were registered + * for icon + */ +RUNNER_TEST(widget_dao_test_register_widget_icons) +{ + WacSecurityMock sec; + WidgetRegisterInfo regInfo; + + ConfigParserData::Icon icon(L"icon1"); + icon.width = 10; + icon.height = 10; + LocaleSet locs; + locs.insert(DPL::FromUTF8String("en")); + WidgetRegisterInfo::LocalizedIcon locIcon(icon, locs); + regInfo.localizationData.icons.push_back(locIcon); + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO dao(tizenAppId); + WidgetDAOReadOnly::WidgetIconList list = dao.getIconList(); + + RUNNER_ASSERT(list.size() == regInfo.localizationData.icons.size()); + WidgetDAOReadOnly::WidgetIconList::const_iterator it1 = list.begin(); + WidgetRegisterInfo::LocalizedIconList::const_iterator it2 = + regInfo.localizationData.icons.begin(); + for (; it1 != list.end() && it2 != regInfo.localizationData.icons.end(); + ++it1, ++it2) + { + RUNNER_ASSERT(it2->height == it1->iconHeight); + RUNNER_ASSERT(it2->width == it1->iconWidth); + RUNNER_ASSERT(it2->src == it1->iconSrc); + RUNNER_ASSERT(it2->availableLocales == locs); + } +} + +/* + * Name: widget_dao_test_register_widget_start_files + * Description: Tests registeration of localized start files + * Expected: no expectations as it should be removed + */ +RUNNER_TEST(widget_dao_test_register_widget_start_files) +{ + WacSecurityMock sec; + + WidgetRegisterInfo::LocalizedStartFileList files; + WidgetRegisterInfo::StartFilePropertiesForLocalesMap map1; + WidgetRegisterInfo::StartFileProperties prop1; + prop1.encoding = DPL::FromUTF8String("enc1"); + prop1.type = DPL::FromUTF8String("type1"); + + map1.insert(std::make_pair(DPL::FromUTF8String("en"), prop1)); + map1.insert(std::make_pair(DPL::FromUTF8String("pl"), prop1)); + + WidgetRegisterInfo::LocalizedStartFile file1; + WidgetRegisterInfo::LocalizedStartFile file2; + file1.path = DPL::FromUTF8String("path1"); + file1.propertiesForLocales = map1; + file2.path = DPL::FromUTF8String("path2"); + file2.propertiesForLocales = map1; + + files.push_back(file1); + files.push_back(file1); + + WidgetRegisterInfo regInfo; + regInfo.localizationData.startFiles = files; + + REGISTER_WIDGET(regInfo, sec); + + //TODO no getter in WidgetDAO (getter in LocalizedWidgetDAO, + // but it will be removed +} + +/* + * Name: widget_dao_test_register_widget_features + * Description: Tests registeration of features of widget + * Expected: number of features should match (for given widget reginfo) + */ +RUNNER_TEST(widget_dao_test_register_widget_features) +{ + WacSecurityMock sec; + ConfigParserData::FeaturesList features; + features.insert(ConfigParserData::Feature(DPL::FromUTF8String("f1"))); + features.insert(ConfigParserData::Feature(DPL::FromUTF8String("f2"))); + features.insert(ConfigParserData::Feature(DPL::FromUTF8String("f3"))); + + WidgetRegisterInfo regInfo; + FOREACH(it, features) + regInfo.configInfo.featuresList.insert(*it); + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO dao(tizenAppId); + WidgetFeatureSet out = dao.getFeaturesList(); + RUNNER_ASSERT_MSG(out.size() == features.size(), + "wrong number of features"); + // FOREACH(it, out) + // RUNNER_ASSERT(features.find(*it) != features.end()); +} + +/* + * Name: widget_dao_test_register_widget_win_modes + * Description: Tests registeration of window modes + * Expected: all modes should be returned from dao + */ +RUNNER_TEST(widget_dao_test_register_widget_win_modes) +{ + WacSecurityMock sec; + std::set modes; + modes.insert(DPL::FromUTF8String("full")); + modes.insert(DPL::FromUTF8String("window")); + + WidgetRegisterInfo regInfo; + + FOREACH(it, modes) + regInfo.configInfo.windowModes.insert(*it); + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO dao(tizenAppId); + std::list wins = dao.getWindowModes(); + RUNNER_ASSERT_MSG(modes.size() == wins.size(), + "wrong number of window modes"); + FOREACH(it, wins) + RUNNER_ASSERT(modes.find(*it) != modes.end()); +} + +/* + * Name: widget_dao_test_register_widget_warp_info + * Description: Tests registeration of access info iris + * Expected: all access info iris should be returned from dao + */ +RUNNER_TEST(widget_dao_test_register_widget_warp_info) +{ + WacSecurityMock sec; + ConfigParserData::AccessInfoSet orig; + orig.insert(ConfigParserData::AccessInfo(DPL::FromUTF8String("iri1"), + true)); + orig.insert(ConfigParserData::AccessInfo(DPL::FromUTF8String("iri2"), + false)); + orig.insert(ConfigParserData::AccessInfo(DPL::FromUTF8String("iri3"), + true)); + + WidgetRegisterInfo regInfo; + FOREACH(it, orig) + regInfo.configInfo.accessInfoSet.insert(*it); + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO dao(tizenAppId); + + WidgetAccessInfoList out; + dao.getWidgetAccessInfo(out); + RUNNER_ASSERT_MSG(out.size() == orig.size(), + "wrong number of access info elem"); + FOREACH(it, out){ + ConfigParserData::AccessInfo tmp(it->strIRI, it->bSubDomains); + RUNNER_ASSERT(orig.find(tmp) != orig.end()); + } +} + +/* + * Name: widget_dao_test_register_widget_certificates + * Description: Tests registeration of widget certificates + * Expected: all certificates should be returned from dao + * and should contain inserted data + */ +RUNNER_TEST(widget_dao_test_register_widget_certificates) +{ + WacSecurityMock sec; + WidgetRegisterInfo regInfo; + + WidgetCertificateData cert; + cert.owner = WidgetCertificateData::AUTHOR; + cert.type = WidgetCertificateData::ROOT; + cert.chainId = 1; + cert.strMD5Fingerprint = "md5"; + cert.strSHA1Fingerprint = "sha1"; + cert.strCommonName = DPL::FromUTF8String("common name"); + + WidgetCertificateDataList& certListRef = sec.getCertificateListRef(); + certListRef.push_back(cert); + + // register widget + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO dao(tizenAppId); + + // certificates + WidgetCertificateDataList recList = dao.getCertificateDataList(); + RUNNER_ASSERT(recList.size() == certListRef.size()); + + auto recListIt = recList.begin(); + auto certListIt = certListRef.begin(); + for (; recListIt != recList.end() && certListIt != certListRef.end(); + ++recListIt, ++certListIt) + { + RUNNER_ASSERT(recListIt->chainId == certListIt->chainId); + RUNNER_ASSERT(recListIt->owner == certListIt->owner); + RUNNER_ASSERT(recListIt->strCommonName == certListIt->strCommonName); + RUNNER_ASSERT(recListIt->strMD5Fingerprint == + certListIt->strMD5Fingerprint); + RUNNER_ASSERT(recListIt->strSHA1Fingerprint == + certListIt->strSHA1Fingerprint); + RUNNER_ASSERT(recListIt->type == certListIt->type); + } + + // fingerprints + RUNNER_ASSERT(dao.getKeyFingerprints(WidgetCertificateData::DISTRIBUTOR, + WidgetCertificateData::ENDENTITY). + empty()); + RUNNER_ASSERT(dao.getKeyFingerprints(WidgetCertificateData::AUTHOR, + WidgetCertificateData::ENDENTITY). + empty()); + RUNNER_ASSERT(dao.getKeyFingerprints(WidgetCertificateData::DISTRIBUTOR, + WidgetCertificateData::ROOT).empty()); + + FingerPrintList fingerprints = dao.getKeyFingerprints( + WidgetCertificateData::AUTHOR, + WidgetCertificateData::ROOT); + + RUNNER_ASSERT(fingerprints.size() == certListRef.size() * 2); + FOREACH(it, certListRef) + { + auto md5 = std::find(fingerprints.begin(), + fingerprints.end(), + it->strMD5Fingerprint); + RUNNER_ASSERT(md5 != fingerprints.end()); + + auto sha = std::find(fingerprints.begin(), + fingerprints.end(), + it->strSHA1Fingerprint); + RUNNER_ASSERT(sha != fingerprints.end()); + } + + // common names + RUNNER_ASSERT(dao.getKeyCommonNameList(WidgetCertificateData::DISTRIBUTOR, + WidgetCertificateData::ENDENTITY). + empty()); + RUNNER_ASSERT(dao.getKeyCommonNameList(WidgetCertificateData::AUTHOR, + WidgetCertificateData::ENDENTITY). + empty()); + RUNNER_ASSERT(dao.getKeyCommonNameList(WidgetCertificateData::DISTRIBUTOR, + WidgetCertificateData::ROOT).empty()); + + FingerPrintList commonNames = dao.getKeyCommonNameList( + WidgetCertificateData::AUTHOR, + WidgetCertificateData::ROOT); + + RUNNER_ASSERT(commonNames.size() == certListRef.size()); + FOREACH(it, certListRef) + { + auto cn = std::find(commonNames.begin(), + commonNames.end(), + DPL::ToUTF8String(it->strCommonName)); + RUNNER_ASSERT(cn != commonNames.end()); + } +} + +/* + * Name: widget_dao_test_register_widget_privileges + * Description: Tests registration of widget privileges + */ +RUNNER_TEST(widget_dao_test_register_widget_privileges) +{ + + WacSecurityMock sec; + WidgetRegisterInfo regInfo; + + ConfigParserData::PrivilegeList& privilegeList = + regInfo.configInfo.privilegeList; + privilegeList.insert(DPL::FromUTF8String("name")); + privilegeList.insert(DPL::FromUTF8String("name2")); + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + WidgetDAO dao(tizenAppId); + + WrtDB::PrivilegeList privListFromDB; + privListFromDB = dao.getWidgetPrivilege(); + + RUNNER_ASSERT(privilegeList.size() == privListFromDB.size()); + + auto privListIt = privilegeList.begin(); + auto privDBIt = privListFromDB.begin(); + for(; privListIt != privilegeList.end() && privDBIt != privListFromDB.end(); + ++privListIt, ++privDBIt) + { + RUNNER_ASSERT(*privDBIt == privListIt->name); + } +} + +/* + * Name: widget_dao_test_register_app_control + * Description: Tests app control + */ +RUNNER_TEST(widget_dao_test_register_app_control) +{ + WacSecurityMock sec; + WidgetRegisterInfo regInfo; + + ConfigParserData::AppControlInfo appControl(DPL::FromUTF8String("operation")); + appControl.m_disposition + = ConfigParserData::AppControlInfo::Disposition::WINDOW; + appControl.m_mimeList.insert(DPL::FromUTF8String("mime")); + appControl.m_src = DPL::FromUTF8String("src"); + appControl.m_uriList.insert(DPL::FromUTF8String("uri")); + + ConfigParserData::AppControlInfoList& appControlListRef + = regInfo.configInfo.appControlList; + appControlListRef.push_back(appControl); + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO dao(tizenAppId); + + WrtDB::WidgetAppControlList appControlInfoListDB; + dao.getAppControlList(appControlInfoListDB); + RUNNER_ASSERT(appControlInfoListDB.size() == appControlListRef.size()); + auto appDBIt = appControlInfoListDB.begin(); + auto appRefIt = appControlListRef.begin(); + + for (;appDBIt != appControlInfoListDB.end() + && appRefIt != appControlListRef.end(); + ++appDBIt, ++appRefIt) + { + RUNNER_ASSERT((WidgetAppControl::Disposition) + appRefIt->m_disposition == appDBIt->disposition); + RUNNER_ASSERT(appRefIt->m_index == appDBIt->index); + RUNNER_ASSERT(appRefIt->m_operation == appDBIt->operation); + RUNNER_ASSERT(appRefIt->m_src == appDBIt->src); + for(auto it = appRefIt->m_mimeList.begin(); + it != appRefIt->m_mimeList.end(); + ++it) + { + RUNNER_ASSERT((*it) == appDBIt->mime); + } + for(auto it = appRefIt->m_uriList.begin(); + it != appRefIt->m_uriList.end(); + ++it) + { + RUNNER_ASSERT((*it) == appDBIt->uri); + } + } +} + +/* + * Name: widget_dao_test_is_widget_installed + * Description: Tests checking if widgets are installed + * Expected: installed widgets should be stated as installed + */ +RUNNER_TEST(widget_dao_test_is_widget_installed) +{ + RUNNER_ASSERT(WidgetDAO::isWidgetInstalled(L"tizenid201")); + + WacSecurityMock sec; + WidgetRegisterInfo regInfo; + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + RUNNER_ASSERT(WidgetDAO::isWidgetInstalled(tizenAppId)); +} + +/* + * Name: widget_dao_test_unregister_widget + * Description: Tests unregistering widgets + * Expected: widget register informations should be successfully removed + */ +RUNNER_TEST(widget_dao_test_unregister_widget) +{ + WacSecurityMock sec; + TizenAppIdList ids = WidgetDAO::getTizenAppidList(); + + WidgetRegisterInfo regInfo; + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO::unregisterWidget(tizenAppId); + + RUNNER_ASSERT_MSG(ids.size() == WidgetDAO::getTizenAppidList().size(), + "Widget unregister failed"); +} + +/* + * Name: widget_dao_test_register_or_update_widget + * Description: Tests reregistering widgets + * Expected: widget should be successfully replaced + */ +RUNNER_TEST(widget_dao_test_register_or_update_widget) +{ + WacSecurityMock sec; + + WidgetRegisterInfo regInfo; + regInfo.configInfo.version = L"1.0"; + regInfo.configInfo.authorName = L"AAA"; + + WidgetRegisterInfo regInfo2; + regInfo2.configInfo.version = L"1.1"; + regInfo2.configInfo.authorName = L"BBB"; + + WrtDB::TizenAppId tizenAppId(L"abcdefghij"); + + //first installation + WidgetDAO::registerWidget(tizenAppId, regInfo, sec); + RUNNER_ASSERT_MSG(WidgetDAO::isWidgetInstalled( + tizenAppId), "Widget is not registered"); + + //success full update + WidgetDAO::updateTizenAppId(tizenAppId, L"backup"); + WidgetDAO::registerWidget(tizenAppId, regInfo2, sec); + WidgetDAO::unregisterWidget(L"backup"); + RUNNER_ASSERT_MSG(WidgetDAO::isWidgetInstalled( + tizenAppId), "Widget is not reregistered"); + WidgetDAO dao(tizenAppId); + RUNNER_ASSERT_MSG( + *dao.getVersion() == L"1.1", "Data widget was not updated"); + RUNNER_ASSERT_MSG( + *dao.getAuthorName() == L"BBB", "Data widget was not updated"); + + + WidgetDAO::unregisterWidget(tizenAppId); +} + +/* + * Name: widget_dao_test_get_widget_tizenAppId_list + * Description: Tests getTizenAppidList API for backendlib + * Expected: For all position in database should be returned one item in list + */ +RUNNER_TEST(widget_dao_test_get_widget_tizenAppId_list) +{ + TizenAppIdList tizenAppIds = WidgetDAO::getTizenAppidList(); + RUNNER_ASSERT(tizenAppIds.size() >= 3); +} + +/* + * Name: widget_dao_test_get_widget_list + * Description: Tests getTizenAppidList API for backendlib + * Expected: For all position in database should be returned one item in list + * Those item should contain valid tizenAppId + */ +RUNNER_TEST(widget_dao_test_get_widget_list) +{ + WidgetDAOReadOnlyList list = WidgetDAOReadOnly::getWidgetList(); + RUNNER_ASSERT(list.size() >= 3); + RUNNER_ASSERT_MSG(!!list.front(), "widget dao exists"); + WidgetDAOReadOnlyPtr dao = list.front(); +} + +/* + * Name: widget_dao_test_get_widget_attributes + * Description: Tests returning basic widget attributes by dao + * Expected: Attributes should match values inserted into database + */ +RUNNER_TEST(widget_dao_test_get_widget_attributes) +{ + { + TizenAppId tizenAppId = L"tizenid201"; + WidgetDAO dao(tizenAppId); + + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getGUID(), "w_id_2000"); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getVersion(), "1.0.0"); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getAuthorName(), "a_name_2000"); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getAuthorEmail(), + "a_email_2000"); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getAuthorHref(), "a_href_2000"); + RUNNER_ASSERT_WHAT_EQUALS(dao.getBaseFolder(), "basef_2000/"); + RUNNER_ASSERT(dao.getWebkitPluginsRequired() == true); + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL(dao.getMinimumWacVersion(), "1.0"); + } +} + +/* + * Name: widget_dao_test_localization + * Description: Tests inserting and returning localization info + * Expected: Values inserted into database should match values received from + * database + */ +RUNNER_TEST(widget_dao_test_localization) +{ + WacSecurityMock sec; + + // icon + WidgetRegisterInfo regInfo; + ConfigParserData::Icon icon(L"icon1"); + icon.width = 10; + icon.height = 10; + LocaleSet locs; + locs.insert(DPL::FromUTF8String("en")); + locs.insert(DPL::FromUTF8String("pl")); + WidgetRegisterInfo::LocalizedIcon locIcon(icon, locs); + regInfo.localizationData.icons.push_back(locIcon); + + //start file + WidgetRegisterInfo::StartFileProperties prop_en; + prop_en.encoding = DPL::FromUTF8String("encoding_en"); + prop_en.type = DPL::FromUTF8String("type_en"); + + WidgetRegisterInfo::StartFileProperties prop_pl; + prop_pl.encoding = DPL::FromUTF8String("encoding_pl"); + prop_pl.type = DPL::FromUTF8String("type_pl"); + + WidgetRegisterInfo::LocalizedStartFile file; + file.path = DPL::FromUTF8String("path"); + file.propertiesForLocales.insert( + std::make_pair(DPL::FromUTF8String("en"), prop_en)); + file.propertiesForLocales.insert( + std::make_pair(DPL::FromUTF8String("pl"), prop_pl)); + regInfo.localizationData.startFiles.push_back(file); + + // register widget + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAO dao(tizenAppId); + + // check localized icons + WidgetDAO::WidgetLocalizedIconList locList = dao.getLocalizedIconList(); + RUNNER_ASSERT(locList.size() == locs.size()); + + // non-localized icon + WidgetDAO::WidgetIconList list = dao.getIconList(); + int iconId = list.front().iconId; + + // compare every icon with the origin + auto locsIt = locs.begin(); + auto iconIt = locList.begin(); + for (; locsIt != locs.end() && iconIt != locList.end(); ++locsIt, + ++iconIt) + { + RUNNER_ASSERT(iconIt->appId == dao.getHandle()); + RUNNER_ASSERT(iconIt->iconId == iconId); + RUNNER_ASSERT(iconIt->widgetLocale == *locsIt); + } + + // localized start file list + WidgetDAO::LocalizedStartFileList fList = dao.getLocalizedStartFileList(); + RUNNER_ASSERT(fList.size() == file.propertiesForLocales.size()); + + int startFileId = dao.getStartFileList().front().startFileId; + + FOREACH(it, fList) + { + RUNNER_ASSERT(it->appId == dao.getHandle()); + auto propIt = file.propertiesForLocales.find(it->widgetLocale); + RUNNER_ASSERT(propIt != file.propertiesForLocales.end()); + RUNNER_ASSERT(it->encoding == propIt->second.encoding); + RUNNER_ASSERT(it->type == propIt->second.type); + RUNNER_ASSERT(it->startFileId == startFileId); + } +} + +/* + * Name: widget_dao_test_register_scp + * Description: Tests inserting and returning scp policy information + * Expected: Value inserted into database should match values received from + * database + */ +RUNNER_TEST(widget_dao_test_register_scp) +{ + WacSecurityMock sec; + WidgetRegisterInfo regInfo; + DPL::OptionalString policy = DPL::FromUTF8String("Some awesome csp policy"); + regInfo.configInfo.cspPolicy = policy; + { + // register widget + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + WidgetDAO dao(tizenAppId); + + RUNNER_ASSERT_WHAT_EQUALS_OPTIONAL( + dao.getCspPolicy(), DPL::ToUTF8String(*policy)); + } +} + +/* + * Name: widget_dao_test_register_csp_empty + * Description: Tests inserting and returning empty csp policy + * Expected: Value inserted into database should match values received from + * database + */ +RUNNER_TEST(widget_dao_test_register_csp_empty) +{ + WacSecurityMock sec; + WidgetRegisterInfo regInfo; + { + // register widget + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + WidgetDAO dao(tizenAppId); + + RUNNER_ASSERT_MSG(dao.getCspPolicy().IsNull(), "Policy is not null"); + } +} + +/* + * Name: widget_dao_test_widget_privileges_basics + * Description: Tests basic operators of privileges + * Expected: operators should behave properly + */ +RUNNER_TEST(widget_dao_test_widget_privileges_basics) +{ + ConfigParserData::Privilege f1(DPL::FromUTF8String("a")); + ConfigParserData::Privilege f2(DPL::FromUTF8String("f2")); + ConfigParserData::Privilege f3(DPL::FromUTF8String("f3")); + ConfigParserData::Privilege f1prim(DPL::FromUTF8String("a")); + + RUNNER_ASSERT_MSG(f1 != f2, "features not equal"); + RUNNER_ASSERT_MSG(f2 != f3, "features not equal"); + RUNNER_ASSERT_MSG(f1 != f3, "features not equal"); + RUNNER_ASSERT_MSG(f1 == f1prim, "features equal"); + + RUNNER_ASSERT(f1 >= f1prim); + RUNNER_ASSERT(f1 <= f1prim); + RUNNER_ASSERT(f1 < f2); + RUNNER_ASSERT(f1 <= f2); + RUNNER_ASSERT(f3 > f2); + RUNNER_ASSERT(f3 >= f2); +} + +/* + * Name: widget_dao_test_widget_preferences_basics + * Description: Tests basic operators of preferences + * Expected: operators should behave properly + */ +RUNNER_TEST(widget_dao_test_widget_preferences_basics) +{ + ConfigParserData::Preference f1(DPL::FromUTF8String("a")); + ConfigParserData::Preference f2(DPL::FromUTF8String("f2")); + ConfigParserData::Preference f3(DPL::FromUTF8String("f3")); + ConfigParserData::Preference f1prim(DPL::FromUTF8String("a")); + + RUNNER_ASSERT_MSG(f1 != f2, "preferences not equal"); + RUNNER_ASSERT_MSG(f2 != f3, "preferences not equal"); + RUNNER_ASSERT_MSG(f1 != f3, "preferences not equal"); + RUNNER_ASSERT_MSG(f1 == f1prim, "preferences equal"); + + RUNNER_ASSERT(f1 >= f1prim); + RUNNER_ASSERT(f1 <= f1prim); + RUNNER_ASSERT(f1 < f2); + RUNNER_ASSERT(f1 <= f2); + RUNNER_ASSERT(f3 > f2); + RUNNER_ASSERT(f3 >= f2); +} + +/* + * Name: widget_dao_test_widget_features_basics + * Description: Tests basic operators of features + * Expected: operators should behave properly + */ +RUNNER_TEST(widget_dao_test_widget_features_basics) +{ + ConfigParserData::Feature f1(DPL::FromUTF8String("a")); + ConfigParserData::Feature f2(DPL::FromUTF8String("f2")); + ConfigParserData::Feature f3(DPL::FromUTF8String("f3")); + ConfigParserData::Feature f1prim(DPL::FromUTF8String("a")); + + RUNNER_ASSERT_MSG(f1 != f2, "features not equal"); + RUNNER_ASSERT_MSG(f2 != f3, "features not equal"); + RUNNER_ASSERT_MSG(f1 != f3, "features not equal"); + RUNNER_ASSERT_MSG(f1 == f1prim, "features equal"); + + RUNNER_ASSERT(f1 >= f1prim); + RUNNER_ASSERT(f1 <= f1prim); + RUNNER_ASSERT(f1 < f2); + RUNNER_ASSERT(f1 <= f2); + RUNNER_ASSERT(f3 > f2); + RUNNER_ASSERT(f3 >= f2); +} + +/* + * Name: widget_dao_test_widget_icons_basics + * Description: Tests basic operators for icons + * Expected: operators should behave properly + */ +RUNNER_TEST(widget_dao_test_widget_icons_basics) +{ + ConfigParserData::Icon f1(DPL::FromUTF8String("a")); + ConfigParserData::Icon f2(DPL::FromUTF8String("f2")); + ConfigParserData::Icon f3(DPL::FromUTF8String("f3")); + ConfigParserData::Icon f1prim(DPL::FromUTF8String("a")); + + RUNNER_ASSERT_MSG(f1 != f2, "icons not equal"); + RUNNER_ASSERT_MSG(f2 != f3, "icons not equal"); + RUNNER_ASSERT_MSG(f1 != f3, "icons not equal"); + RUNNER_ASSERT_MSG(f1 == f1prim, "icons equal"); + + RUNNER_ASSERT(f1 >= f1prim); + RUNNER_ASSERT(f1 <= f1prim); + RUNNER_ASSERT(f1 < f2); + RUNNER_ASSERT(f1 <= f2); + RUNNER_ASSERT(f3 > f2); + RUNNER_ASSERT(f3 >= f2); +} + +/* + * Name: widget_dao_test_widget_settings_basics + * Description: Tests basic operators for settings of widget + * Expected: operators should behave properly + */ +RUNNER_TEST(widget_dao_test_widget_settings_basics) +{ + ConfigParserData::Setting f1(DPL::FromUTF8String("a"), DPL::FromUTF8String("1")); + ConfigParserData::Setting f2(DPL::FromUTF8String("a"), DPL::FromUTF8String("2")); + ConfigParserData::Setting f3(DPL::FromUTF8String("b"), DPL::FromUTF8String("2")); + ConfigParserData::Setting f1prim(DPL::FromUTF8String("a"), DPL::FromUTF8String("1")); + + RUNNER_ASSERT_MSG(f1 != f2, "settings not equal"); + RUNNER_ASSERT_MSG(f2 != f3, "settings not equal"); + RUNNER_ASSERT_MSG(f1 != f3, "settings not equal"); + RUNNER_ASSERT_MSG(f1 == f1prim, "settings equal"); + + RUNNER_ASSERT(f1 >= f1prim); + RUNNER_ASSERT(f1 <= f1prim); + RUNNER_ASSERT(f1 <= f2); + RUNNER_ASSERT(f3 > f2); + RUNNER_ASSERT(f2 < f3); + RUNNER_ASSERT(f3 >= f2); +} + +/* + * Name: widget_dao_test_widget_access_basics + * Description: Tests basic operators for access of widget + * Expected: operators should behave properly + */ +RUNNER_TEST(widget_dao_test_widget_access_basics) +{ + ConfigParserData::AccessInfo a(DPL::FromUTF8String("a"), true); + ConfigParserData::AccessInfo b(DPL::FromUTF8String("b"), true); + ConfigParserData::AccessInfo a1(DPL::FromUTF8String("a"), true); + ConfigParserData::AccessInfo a2(DPL::FromUTF8String("a"), false); + + RUNNER_ASSERT_MSG(a != b, "access info not equal"); + RUNNER_ASSERT_MSG(a == a1, "access info equal"); + RUNNER_ASSERT_MSG(b == b, "access info equal"); + RUNNER_ASSERT_MSG(a1 != b, "access info are not equal"); + RUNNER_ASSERT_MSG(a1 != a2, "access info are not equal"); + RUNNER_ASSERT(a2 < a1); + RUNNER_ASSERT(a1 < b); +} + +/* + * Name: widget_dao_test_widget_metadata_basics + * Description: Tests basic operators for metadata + * Expected: operators should behave properly + */ +RUNNER_TEST(widget_dao_test_widget_metadata_basics) +{ + ConfigParserData::Metadata a(DPL::FromUTF8String("a"), DPL::FromUTF8String("1")); + ConfigParserData::Metadata b(DPL::FromUTF8String("b"), DPL::FromUTF8String("1")); + ConfigParserData::Metadata a1(DPL::FromUTF8String("a"), DPL::FromUTF8String("1")); + ConfigParserData::Metadata a2(DPL::FromUTF8String("a"), DPL::FromUTF8String("2")); + + RUNNER_ASSERT_MSG(a != b, "metadata not equal"); + RUNNER_ASSERT_MSG(a == a1, "metadata equal"); + RUNNER_ASSERT_MSG(b == b, "metadata equal"); + RUNNER_ASSERT_MSG(a1 != b, "metadata not equal"); + RUNNER_ASSERT_MSG(a1 != a2, "metadata not equal"); +} + +/* + * Name: widget_dao_test_widget_appcontrolinfo_basics + * Description: Tests basic operators for app control info + * Expected: operators should behave properly + */ +RUNNER_TEST(widget_dao_test_widget_appcontrolinfo_basics) +{ + ConfigParserData::AppControlInfo a(DPL::FromUTF8String("operation")); + a.m_disposition = ConfigParserData::AppControlInfo::Disposition::WINDOW; + a.m_mimeList.insert(DPL::FromUTF8String("mime")); + a.m_src = DPL::FromUTF8String("src"); + a.m_uriList.insert(DPL::FromUTF8String("uri")); + + ConfigParserData::AppControlInfo a0(DPL::FromUTF8String("operation1")); + a0.m_disposition = ConfigParserData::AppControlInfo::Disposition::WINDOW; + a0.m_mimeList.insert(DPL::FromUTF8String("mime")); + a0.m_src = DPL::FromUTF8String("src"); + a0.m_uriList.insert(DPL::FromUTF8String("uri")); + + ConfigParserData::AppControlInfo a1(DPL::FromUTF8String("operation")); + a1.m_disposition = ConfigParserData::AppControlInfo::Disposition::UNDEFINE; + a1.m_mimeList.insert(DPL::FromUTF8String("mime")); + a1.m_src = DPL::FromUTF8String("src"); + a1.m_uriList.insert(DPL::FromUTF8String("uri")); + + ConfigParserData::AppControlInfo a2(DPL::FromUTF8String("operation")); + a2.m_disposition = ConfigParserData::AppControlInfo::Disposition::WINDOW; + a2.m_mimeList.insert(DPL::FromUTF8String("mime1")); + a2.m_src = DPL::FromUTF8String("src"); + a2.m_uriList.insert(DPL::FromUTF8String("uri")); + + ConfigParserData::AppControlInfo a3(DPL::FromUTF8String("operation")); + a3.m_disposition = ConfigParserData::AppControlInfo::Disposition::WINDOW; + a3.m_mimeList.insert(DPL::FromUTF8String("mime")); + a3.m_src = DPL::FromUTF8String("src1"); + a3.m_uriList.insert(DPL::FromUTF8String("uri")); + + ConfigParserData::AppControlInfo a4(DPL::FromUTF8String("operation")); + a4.m_disposition = ConfigParserData::AppControlInfo::Disposition::WINDOW; + a4.m_mimeList.insert(DPL::FromUTF8String("mime")); + a4.m_src = DPL::FromUTF8String("src"); + a4.m_uriList.insert(DPL::FromUTF8String("uri1")); + + ConfigParserData::AppControlInfo a5(DPL::FromUTF8String("operation")); + a5.m_disposition = ConfigParserData::AppControlInfo::Disposition::WINDOW; + a5.m_mimeList.insert(DPL::FromUTF8String("mime")); + a5.m_src = DPL::FromUTF8String("src"); + a5.m_uriList.insert(DPL::FromUTF8String("uri")); + + RUNNER_ASSERT_MSG(a != a0, "app control info not equal"); + RUNNER_ASSERT_MSG(a != a1, "app control info not equal"); + RUNNER_ASSERT_MSG(a != a2, "app control info not equal"); + RUNNER_ASSERT_MSG(a != a3, "app control info not equal"); + RUNNER_ASSERT_MSG(a != a4, "app control info not equal"); + RUNNER_ASSERT_MSG(a == a5, "app control info equal"); + RUNNER_ASSERT_MSG(a == a, "app control info equal"); +} + +/* + * Name: widget_dao_test_widget_metadata_basics + * Description: Tests basic operators for livebox info + * Expected: operators should behave properly + */ +RUNNER_TEST(widget_dao_test_widget_livebox_basics) +{ + ConfigParserData::LiveboxInfo a; + a.m_icon = DPL::FromUTF8String("icon"); + a.m_liveboxId = DPL::FromUTF8String("id"); + a.m_autoLaunch = DPL::FromUTF8String("auto"); + a.m_updatePeriod = DPL::FromUTF8String("period"); + a.m_primary = DPL::FromUTF8String("primary"); + + ConfigParserData::LiveboxInfo a0; + a0.m_icon = DPL::FromUTF8String("icon0"); + a0.m_liveboxId = DPL::FromUTF8String("id"); + a0.m_autoLaunch = DPL::FromUTF8String("auto"); + a0.m_updatePeriod = DPL::FromUTF8String("period"); + a0.m_primary = DPL::FromUTF8String("primary"); + + ConfigParserData::LiveboxInfo a1; + a1.m_icon = DPL::FromUTF8String("icon"); + a1.m_liveboxId = DPL::FromUTF8String("id0"); + a1.m_autoLaunch = DPL::FromUTF8String("auto"); + a1.m_updatePeriod = DPL::FromUTF8String("period"); + a1.m_primary = DPL::FromUTF8String("primary"); + + ConfigParserData::LiveboxInfo a2; + a2.m_icon = DPL::FromUTF8String("icon"); + a2.m_liveboxId = DPL::FromUTF8String("id"); + a2.m_autoLaunch = DPL::FromUTF8String("auto0"); + a2.m_updatePeriod = DPL::FromUTF8String("period"); + a2.m_primary = DPL::FromUTF8String("primary"); + + ConfigParserData::LiveboxInfo a3; + a3.m_icon = DPL::FromUTF8String("icon"); + a3.m_liveboxId = DPL::FromUTF8String("id"); + a3.m_autoLaunch = DPL::FromUTF8String("auto"); + a3.m_updatePeriod = DPL::FromUTF8String("period0"); + a3.m_primary = DPL::FromUTF8String("primary"); + + ConfigParserData::LiveboxInfo a4; + a4.m_icon = DPL::FromUTF8String("icon"); + a4.m_liveboxId = DPL::FromUTF8String("id"); + a4.m_autoLaunch = DPL::FromUTF8String("auto"); + a4.m_updatePeriod = DPL::FromUTF8String("period"); + a4.m_primary = DPL::FromUTF8String("primary0"); + + ConfigParserData::LiveboxInfo a5; + a5.m_icon = DPL::FromUTF8String("icon"); + a5.m_liveboxId = DPL::FromUTF8String("id"); + a5.m_autoLaunch = DPL::FromUTF8String("auto"); + a5.m_updatePeriod = DPL::FromUTF8String("period"); + a5.m_primary = DPL::FromUTF8String("primary"); + + const DPL::String s1 = DPL::FromUTF8String("1"); + const DPL::String s2 = DPL::FromUTF8String("2"); + + ConfigParserData::LiveboxInfo a10; + a10.m_icon = DPL::FromUTF8String("icon"); + a10.m_liveboxId = DPL::FromUTF8String("id"); + a10.m_autoLaunch = DPL::FromUTF8String("auto"); + a10.m_updatePeriod = DPL::FromUTF8String("period"); + a10.m_primary = DPL::FromUTF8String("primary"); + a10.m_label.push_back(std::pair(s1, s1)); + + ConfigParserData::LiveboxInfo a11; + a11.m_icon = DPL::FromUTF8String("icon"); + a11.m_liveboxId = DPL::FromUTF8String("id"); + a11.m_autoLaunch = DPL::FromUTF8String("auto"); + a11.m_updatePeriod = DPL::FromUTF8String("period"); + a11.m_primary = DPL::FromUTF8String("primary"); + a11.m_label.push_back(std::pair(s1, s2)); + a11.m_label.push_back(std::pair(s1, s2)); + + ConfigParserData::LiveboxInfo a12; + a12.m_icon = DPL::FromUTF8String("icon"); + a12.m_liveboxId = DPL::FromUTF8String("id"); + a12.m_autoLaunch = DPL::FromUTF8String("auto"); + a12.m_updatePeriod = DPL::FromUTF8String("period"); + a12.m_primary = DPL::FromUTF8String("primary"); + a12.m_label.push_back(std::pair(s1, s1)); + + RUNNER_ASSERT_MSG(a != a0, "livebox info not equal"); + RUNNER_ASSERT_MSG(a != a1, "livebox info not equal"); + RUNNER_ASSERT_MSG(a != a2, "livebox info not equal"); + RUNNER_ASSERT_MSG(a != a3, "livebox info not equal"); + RUNNER_ASSERT_MSG(a != a4, "livebox info not equal"); + RUNNER_ASSERT_MSG(a == a5, "livebox info equal"); + RUNNER_ASSERT_MSG(a == a, "livebox info equal"); + RUNNER_ASSERT_MSG(a10 != a11, "livebox info not equal"); + RUNNER_ASSERT_MSG(a10 == a12, "livebox info equal"); +} + +/* + * Name: widget_dao_test_get_widget_by_guid + * Description: Tests creating WidgetDAO using GUID + * Expected: Correct WidgetDAO should be created + */ +RUNNER_TEST(widget_dao_test_get_widget_by_guid) +{ + WidgetDAO dao(DPL::OptionalString(L"w_id_2000")); + RUNNER_ASSERT(dao.getTizenAppId() == L"tizenid201"); +} + +/* + * Name: widget_dao_test_set_tizen_app_id + * Description: Tests changing TizenAppId + * Expected: Change should be possible + */ +RUNNER_TEST(widget_dao_test_set_tizen_app_id) +{ + WacSecurityMock sec; + WidgetRegisterInfo regInfo; + TizenAppId originaltizenAppId = REGISTER_WIDGET(regInfo, sec); + TizenAppId changedTizenAppId = L"changedTizenAppId"; + + TizenAppIdList ids = WidgetDAO::getTizenAppidList(); + RUNNER_ASSERT(std::count(ids.begin(),ids.end(),originaltizenAppId) == 1); + + //Change tizenAppId + WidgetDAO dao(originaltizenAppId); + dao.setTizenAppId(changedTizenAppId); + + ids = WidgetDAO::getTizenAppidList(); + RUNNER_ASSERT(std::count(ids.begin(), ids.end(), originaltizenAppId) == 0); + RUNNER_ASSERT(std::count(ids.begin(), ids.end(), changedTizenAppId) == 1); + + bool exceptionCaught = checkException < WidgetDAOReadOnly::Exception::WidgetNotExist > ([&]() { + WidgetDAO dao2(originaltizenAppId); + //Changing should fail because original tizenAppId doesn't exist any more. + dao2.setTizenAppId(changedTizenAppId); + }); + RUNNER_ASSERT(exceptionCaught); + + WidgetDAO::unregisterWidget(changedTizenAppId); + ids = WidgetDAO::getTizenAppidList(); + RUNNER_ASSERT(std::count(ids.begin(),ids.end(),originaltizenAppId) == 0); + RUNNER_ASSERT(std::count(ids.begin(),ids.end(),changedTizenAppId) == 0); + +} + +/* + * Name: widget_dao_test_update_feature_reject_status + * Description: Tests updating feature reject status + * Expected: Reject status should be properly updated + */ +RUNNER_TEST(widget_dao_test_update_feature_reject_status) +{ + WidgetDAO dao(L"tizenid202"); + DbWidgetFeatureSet featureSet = dao.getFeaturesList(); + + RUNNER_ASSERT(featureSet.size() == 1); + DbWidgetFeature feature = *featureSet.begin(); + RUNNER_ASSERT(!feature.rejected); + + feature.rejected = true; + dao.updateFeatureRejectStatus(feature); + + featureSet = dao.getFeaturesList(); + RUNNER_ASSERT(featureSet.size() == 1); + DbWidgetFeature feature2 = *featureSet.begin(); + RUNNER_ASSERT(feature.rejected); + + feature2.rejected = false; + dao.updateFeatureRejectStatus(feature2); +} + +/* + * Name: widget_dao_test_register_widget_allow_navigation + * Description: Tests AllowNavigationInfo registration + * Expected: AllowNavigationInfo registration should be possible + */ +RUNNER_TEST(widget_dao_test_register_widget_allow_navigation) +{ + WacSecurityMock sec; + WidgetRegisterInfo regInfo; + ConfigParserData::AllowNavigationInfo navigationInfo1(L"scheme1", L"host1"); + ConfigParserData::AllowNavigationInfo navigationInfo2(L"scheme2", L"host2"); + regInfo.configInfo.allowNavigationInfoList.push_back(navigationInfo1); + regInfo.configInfo.allowNavigationInfoList.push_back(navigationInfo2); + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAOReadOnly dao(tizenAppId); + WidgetAllowNavigationInfoList navigationList; + dao.getWidgetAllowNavigationInfo(navigationList); + + RUNNER_ASSERT(navigationList.size() == 2); + RUNNER_ASSERT( + std::count_if(navigationList.begin(), navigationList.end(), [] (const WidgetAllowNavigationInfo& navInfo) + { return navInfo.host == L"host1" && navInfo.scheme == L"scheme1"; }) == 1); + RUNNER_ASSERT( + std::count_if(navigationList.begin(), navigationList.end(), [] (const WidgetAllowNavigationInfo& navInfo) + { return navInfo.host == L"host2" && navInfo.scheme == L"scheme2"; }) == 1); + +} + +/* + * Name: widget_dao_test_register_external_locations + * Description: Tests ExternalLocation registration + * Expected: ExternalLocation registration should be possible + */ +RUNNER_TEST(widget_dao_test_register_external_locations) +{ + WacSecurityMock sec; + WidgetRegisterInfo regInfo; + regInfo.externalLocations.push_back("location1"); + regInfo.externalLocations.push_back("location2"); + + TizenAppId tizenAppId = REGISTER_WIDGET(regInfo, sec); + + WidgetDAOReadOnly dao(tizenAppId); + ExternalLocationList locationList = dao.getWidgetExternalLocations(); + + RUNNER_ASSERT(locationList.size() == 2); + RUNNER_ASSERT(std::count(locationList.begin(), locationList.end(), "location1") == 1); + RUNNER_ASSERT(std::count(locationList.begin(), locationList.end(), "location2") == 1); +} + + /* + * Name: widget_dao_test_get_tz_app_id + * Description: Tests getTizenAppId functions + * Expected: TizenAppId is correctly fetched for correct widgets, exception for not existing. + */ +RUNNER_TEST(widget_dao_test_get_tz_app_id) +{ + //No such widget + RUNNER_ASSERT_EXCEPTION(WidgetDAOReadOnly::Exception::WidgetNotExist, WidgetDAOReadOnly::getTizenAppId(1234); ); + + TizenAppId appId = WidgetDAOReadOnly::getTizenAppId(2001); + RUNNER_ASSERT(L"tizenid202" == appId); + + RUNNER_ASSERT_EXCEPTION(WidgetDAOReadOnly::Exception::WidgetNotExist, WidgetDAOReadOnly::getTizenAppId(L"no_such_widget"); ); + + appId = WidgetDAOReadOnly::getTizenAppId(L"pkgid202"); + RUNNER_ASSERT(L"tizenid202" == appId); +} + +/* + * Name: widget_dao_test_get_tz_pkg_id + * Description: Tests getTizenPkgId functions + * Expected: TizenPkgId is correctly fetched for correct widgets, exception for not existing. + */ +RUNNER_TEST(widget_dao_test_get_tz_pkg_id) +{ + //No such widget + RUNNER_ASSERT_EXCEPTION(WidgetDAOReadOnly::Exception::WidgetNotExist, WidgetDAOReadOnly::getTizenPkgId(1234); ); + + + TizenPkgId pkgId = WidgetDAOReadOnly::getTizenPkgId(2001); + RUNNER_ASSERT(L"pkgid202" == pkgId); + + RUNNER_ASSERT_EXCEPTION(WidgetDAOReadOnly::Exception::WidgetNotExist, WidgetDAOReadOnly::getTizenPkgId(L"no_such_widget");); + + pkgId = WidgetDAOReadOnly::getTizenPkgId(L"tizenid202"); + RUNNER_ASSERT(L"pkgid202" == pkgId); +} + +/* + * Name: widget_dao_test_get_property_key + * Description: Tests getPropertyKeyList function + * Expected: Property keys are fetched correctly. + */ +RUNNER_TEST(widget_dao_test_get_property_key) +{ + WidgetDAOReadOnly dao(L"tizenid201"); + PropertyDAOReadOnly::WidgetPropertyKeyList propertyKeys = dao.getPropertyKeyList(); + + RUNNER_ASSERT(propertyKeys.size() == 2); + RUNNER_ASSERT(std::count(propertyKeys.begin(), propertyKeys.end(), L"key1_for_2000") == 1); + RUNNER_ASSERT(std::count(propertyKeys.begin(), propertyKeys.end(), L"key2_for_2000") == 1); +} + +/* + * Name: widget_dao_test_get_property_value + * Description: Tests getPropertyValue function + * Expected: Property key values are fetched correctly. + */ +RUNNER_TEST(widget_dao_test_get_property_value) +{ + WidgetDAOReadOnly dao(L"tizenid201"); + + RUNNER_ASSERT(dao.getPropertyValue(L"key1_for_2000") == L"value_for_key1_2000"); + RUNNER_ASSERT(dao.getPropertyValue(L"key2_for_2000") == L"value_for_key2_2000"); + RUNNER_ASSERT(dao.getPropertyValue(L"not_existing").IsNull()); + RUNNER_ASSERT(dao.getPropertyValue(L"").IsNull()); +} + +/* + * Name: widget_dao_test_get_property_read_flag + * Description: Tests checkPropertyReadFlag function + * Expected: Property read flags values are fetched correctly. + */ +RUNNER_TEST(widget_dao_test_get_property_read_flag) +{ + WidgetDAOReadOnly dao(L"tizenid201"); + + RUNNER_ASSERT(dao.checkPropertyReadFlag(L"key1_for_2000") == 0); + RUNNER_ASSERT(dao.checkPropertyReadFlag(L"key2_for_2000") == 0); + RUNNER_ASSERT(dao.checkPropertyReadFlag(L"not_existing").IsNull()); + RUNNER_ASSERT(dao.checkPropertyReadFlag(L"").IsNull()); +} + +/* + * Name: widget_dao_test_get_pkg_id_list + * Description: Tests getTizenPkgIdList function + * Expected: All pkg ids are returned. + */ +RUNNER_TEST(widget_dao_test_get_pkg_id_list) +{ + TizenPkgIdList pkgIds = WidgetDAOReadOnly::getTizenPkgIdList(); + + RUNNER_ASSERT(pkgIds.size() == 4); + RUNNER_ASSERT(std::count(pkgIds.begin(), pkgIds.end(), L"pkgid201") == 1); + RUNNER_ASSERT(std::count(pkgIds.begin(), pkgIds.end(), L"pkgid202") == 1); + RUNNER_ASSERT(std::count(pkgIds.begin(), pkgIds.end(), L"") == 2); +} + +/* + * Name: widget_dao_test_get_back_supported + * Description: Tests getBackSupported function + * Expected: Back supported information is fetched properly. + */ +RUNNER_TEST(widget_dao_test_get_back_supported) +{ + WidgetDAOReadOnly dao1(L"tizenid201"); + RUNNER_ASSERT(dao1.getBackSupported()); + + WidgetDAOReadOnly dao2(L"tizenid202"); + RUNNER_ASSERT(!dao2.getBackSupported()); +} + +/* + * Name: widget_dao_test_get_csp_policy_report + * Description: Tests getCspPolicyReportOnly function + * Expected: CSP policy information is fetched properly. + */ +RUNNER_TEST(widget_dao_test_get_csp_policy_report) +{ + WidgetDAOReadOnly dao1(L"tizenid201"); + RUNNER_ASSERT(DPL::OptionalString(L"policy_report201") == dao1.getCspPolicyReportOnly()); + + WidgetDAOReadOnly dao2(L"tizenid202"); + RUNNER_ASSERT(DPL::OptionalString(L"policy_report202") == dao2.getCspPolicyReportOnly()); +} + +/* + * Name: widget_dao_test_get_install_time + * Description: Tests getInstallTime function + * Expected: Installation time is fetched properly. + */ +RUNNER_TEST(widget_dao_test_get_install_time) +{ + WidgetDAOReadOnly dao1(L"tizenid201"); + RUNNER_ASSERT(1256 == dao1.getInstallTime()); + + WidgetDAOReadOnly dao2(L"tizenid202"); + RUNNER_ASSERT(5687 == dao2.getInstallTime()); +} + +/* + * Name: widget_dao_test_get_icon_language_tags + * Description: Tests getIconLanguageTags function + * Expected: Information about icon localization is fetched properly. + */ +RUNNER_TEST(widget_dao_test_get_icon_language_tags) +{ + WidgetDAOReadOnly dao1(L"tizenid201"); + LanguageTags languageTags = dao1.getIconLanguageTags(); + + RUNNER_ASSERT(2 == languageTags.size()); + RUNNER_ASSERT(std::count(languageTags.begin(), languageTags.end(), L"en") == 1); + RUNNER_ASSERT(std::count(languageTags.begin(), languageTags.end(), L"pl") == 1); +} + +#undef RUNNER_ASSERT_WHAT_EQUALS diff --git a/tests/dao/TestCases_WidgetInterfaceDAO.cpp b/tests/dao/TestCases_WidgetInterfaceDAO.cpp new file mode 100644 index 0000000..fae5e11 --- /dev/null +++ b/tests/dao/TestCases_WidgetInterfaceDAO.cpp @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file TestCases_widgetInterfaceDAO.cpp + * @author Dominik Duda (d.duda@samsung.com) + * @version 1.0 + * @brief This file contains tests for WidgetInterfaceDAO class. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WIDGET_ID 2000 + +using namespace WrtDB; +using namespace WidgetInterfaceDB; + +RUNNER_TEST_GROUP_INIT(DAO) + +/* + * Name: widget_interface_dao_test_01_initialization + * Description: Tests database creation. + * Expected: The database should be successfully created. + */ +RUNNER_TEST(widget_interface_dao_test_01_initialization) +{ + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_01_initialization_Exception + * Description: Tests if an exception will be thrown when incorrect widgetID + * is used. + * Expected: The exception should be thrown. + */ +RUNNER_TEST(widget_interface_dao_test_01_initialization_Exception) +{ + Try + { + WidgetInterfaceDAO dao(5555000); + } + Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) + { + RUNNER_ASSERT_MSG(true, _rethrown_exception.GetMessage()); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_02_readValue + * Description: Tests getting a value for a given key. + * Expected: The desired value should be returned. + */ +RUNNER_TEST(widget_interface_dao_test_02_readValue) +{ + DPL::Optional value; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + value = dao.getValue("key1_for_2000"); + + RUNNER_ASSERT(value == "value_for_key1_2000"); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_02_readValue_badKey + * Description: Tests if an empty value is returned for an incorrect key. + * Expected: The empty (NULL) value should be returned. + */ +RUNNER_TEST(widget_interface_dao_test_02_readValue_badKey) +{ + DPL::Optional value; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + value = dao.getValue("key1_for_200011111"); + + RUNNER_ASSERT(value.IsNull()); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_03_setItem + * Description: Tests if a new readonly item can be add into a database. + * Expected: The new item should be successfully added. + */ +RUNNER_TEST(widget_interface_dao_test_03_setItem) +{ + DPL::Optional value; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + dao.setItem("key3_for_2000", "value_for_key3_2000", 1); + + value = dao.getValue("key3_for_2000"); + + RUNNER_ASSERT(value == "value_for_key3_2000"); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_03_setItem_Exception + * Description: Tests if a readonly item can be overwritten. + * Expected: An exception should be thrown. + */ +RUNNER_TEST(widget_interface_dao_test_03_setItem_Exception) +{ + DPL::Optional value; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + dao.setItem("key3_for_2000", "value_for_key3_2000", 1); + + RUNNER_ASSERT_MSG(false, "Readonly value should not be overwritten"); + } + Catch(WidgetInterfaceDAO::Exception::LocalStorageValueNoModifableException) + { + RUNNER_ASSERT(true); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_04_setItem + * Description: Tests inserting a new item with non readonly and fromConfigXML + * properties set. + * Expected: The new item should be added. + */ +RUNNER_TEST(widget_interface_dao_test_04_setItem) +{ + DPL::Optional value; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + dao.setItem("key4_for_2000", "value_for_key4_2000", 0, 1); + + value = dao.getValue("key4_for_2000"); + + RUNNER_ASSERT(value == "value_for_key4_2000"); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_05_getKeyByIndex + * Description: Tests getting a key by a given index. + * Expected: The key should be successfully read. + */ +RUNNER_TEST(widget_interface_dao_test_05_getKeyByIndex) +{ + std::string key; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + key = dao.getKeyByIndex(1); + + RUNNER_ASSERT(key == "key2_for_2000"); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_05_getKeyByIndex_badIndex_01 + * Description: Tests if an exception will be thrown when getting a key + * by a negative index. + * Expected: An exception should be thrown. + */ +RUNNER_TEST(widget_interface_dao_test_05_getKeyByIndex_badIndex_01) +{ + std::string key; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + key = dao.getKeyByIndex(-111); + + RUNNER_ASSERT_MSG(false, "A key should not be returned for " + "a negative index!"); + } + Catch(WidgetInterfaceDAO::Exception::InvalidArgumentException) + { + RUNNER_ASSERT_MSG(true, _rethrown_exception.GetMessage()); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_05_getKeyByIndex_badIndex_02 + * Description: Tests if an exception will be thrown when getting a key + * by a non existing index. + * Expected: An exception should be thrown. + */ +RUNNER_TEST(widget_interface_dao_test_05_getKeyByIndex_badIndex_02) +{ + std::string key; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + key = dao.getKeyByIndex(1111); + + RUNNER_ASSERT_MSG(false, "A key should not be returned for " + "a non existing index!"); + } + Catch(WidgetInterfaceDAO::Exception::InvalidArgumentException) + { + RUNNER_ASSERT(true); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_06_removeItem + * Description: Tests removing an item for a given key. + * Expected: An item should be successfully removed. The table size should be + * smaller after removing. + */ +RUNNER_TEST(widget_interface_dao_test_06_removeItem) +{ + std::string key; + size_t sizeBefore, sizeAfter; + DPL::Optional value; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + sizeBefore = dao.getStorageSize(); + + if (sizeBefore == 0) + { + RUNNER_ASSERT_MSG(false, "Database is empty!"); + return; + } + + dao.removeItem("key4_for_2000"); + + sizeAfter = dao.getStorageSize(); + value = dao.getValue("key4_for_2000"); + + RUNNER_ASSERT(sizeAfter == sizeBefore - 1); + RUNNER_ASSERT(value.IsNull()); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_06_removeItem_Exception + * Description: Tests if an exception will be thrown when a readonly item + * is removed. + * Expected: An exception should be thrown. + */ +RUNNER_TEST(widget_interface_dao_test_06_removeItem_Exception) +{ + WidgetInterfaceDAO* dao = NULL; + DPL::Optional value; + size_t sizeBefore, sizeAfter; + + Try + { + dao = new WidgetInterfaceDAO(WIDGET_ID); + + sizeBefore = dao->getStorageSize(); + + if (sizeBefore == 0) + { + RUNNER_ASSERT_MSG(false, "Database is empty!"); + return; + } + + dao->removeItem("key3_for_2000"); + + RUNNER_ASSERT_MSG(false, "A readonly item should not be removed!"); + } + Catch(WidgetInterfaceDAO::Exception::LocalStorageValueNoModifableException) + { + sizeAfter = dao->getStorageSize(); + value = dao->getValue("key3_for_2000"); + + RUNNER_ASSERT(sizeAfter == sizeBefore); + RUNNER_ASSERT(value == "value_for_key3_2000"); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } + + if (dao != NULL) + delete dao; +} + +/* + * Name: widget_interface_dao_test_07_clear + * Description: Tests removing all non readonly rows from the table. + * Expected: The size of the table should be smaller than before removing rows. + */ +RUNNER_TEST(widget_interface_dao_test_07_clear) +{ + size_t sizeBefore, sizeAfter; + DPL::Optional value; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + sizeBefore = dao.getStorageSize(); + dao.clear(false); + + sizeAfter = dao.getStorageSize(); + value = dao.getValue("key3_for_2000"); + + RUNNER_ASSERT(sizeAfter == 1); + RUNNER_ASSERT(sizeAfter < sizeBefore); + RUNNER_ASSERT(value == "value_for_key3_2000"); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} + +/* + * Name: widget_interface_dao_test_07_clearAll + * Description: Tests removing all rows from the table. + * Expected: The size of the table should be 0. + */ +RUNNER_TEST(widget_interface_dao_test_07_clearAll) +{ + size_t sizeAfter; + + Try + { + WidgetInterfaceDAO dao(WIDGET_ID); + + dao.clear(true); + sizeAfter = dao.getStorageSize(); + + RUNNER_ASSERT(sizeAfter == 0); + } + Catch(WidgetInterfaceDAO::Exception::DatabaseError) + { + RUNNER_ASSERT_MSG(false, _rethrown_exception.GetMessage()); + } +} diff --git a/tests/dao/tests_dao.cpp b/tests/dao/tests_dao.cpp new file mode 100644 index 0000000..ae3c7cd --- /dev/null +++ b/tests/dao/tests_dao.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file tests_plugin_dao.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains tests for plugin dao class. + */ + +#include +#include +#include +#include + +int main (int argc, char *argv[]) +{ + int ret = system("/usr/bin/wrt_dao_tests_prepare_db.sh start"); + if (ret != 0) { + LogError("Preparation script has return error: " << ret + << ". Quitting"); + return -1; + } + + WrtDB::WrtDatabase::attachToThreadRW(); + CustomHandlerDB::Interface::attachDatabaseRW(); + + LogDebug("Starting tests"); + int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, + argv); + + CustomHandlerDB::Interface::detachDatabase(); + WrtDB::WrtDatabase::detachFromThread(); + + ret = system("/usr/bin/wrt_dao_tests_prepare_db.sh stop"); + if (ret != 0) { + LogError("Finalization script has return error: " << ret); + return -1; + } + return status; +} diff --git a/tests/dao/wrt_dao_tests_prepare_db.sh b/tests/dao/wrt_dao_tests_prepare_db.sh new file mode 100755 index 0000000..4bb3f0e --- /dev/null +++ b/tests/dao/wrt_dao_tests_prepare_db.sh @@ -0,0 +1,151 @@ +#!/bin/sh +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +WRT_DB=/opt/dbspace/.wrt.db +WRT_DB_BCK=/tmp/wrt.db_backup + +if [ "x$1" == "xstart" ]; then + echo start; + cp $WRT_DB $WRT_DB_BCK + wrt_commons_create_clean_db.sh; + + #simple plugins + INS_MIN_PLUGINPROP="insert into PluginProperties(PluginPropertiesId, InstallationState, PluginLibraryName" + INS_ALL_PLUGINPROP="insert into PluginProperties(PluginPropertiesId, InstallationState, PluginLibraryName, PluginLibraryPath)" + INS_PLUGIN_OBJECTS="insert into PluginImplementedObjects(PluginObject, PluginPropertiesId)" + INS_PLUGIN_DEPEND="insert into PluginDependencies(PluginPropertiesId, RequiredPluginPropertiesId)" + + sqlite3 $WRT_DB "${INS_MIN_PLUGINPROP}) VALUES(1, 1, 'plugin1')"; + sqlite3 $WRT_DB "${INS_MIN_PLUGINPROP}, PluginLibraryPath) VALUES(2, 1, 'plugin2', 'path_to_plugin2')"; + sqlite3 $WRT_DB "${INS_MIN_PLUGINPROP}) VALUES(3, 1, 'plugin3')"; + sqlite3 $WRT_DB "${INS_ALL_PLUGINPROP} VALUES(4, 1, 'p4', 'path_to_p4')"; + sqlite3 $WRT_DB "${INS_ALL_PLUGINPROP} VALUES(5, 1, 'p5', 'path_to_p5')"; + + #plugin dependendencies + sqlite3 $WRT_DB "${INS_PLUGIN_DEPEND} VALUES(1, 5)"; + sqlite3 $WRT_DB "${INS_PLUGIN_DEPEND} VALUES(1, 4)"; + sqlite3 $WRT_DB "${INS_PLUGIN_DEPEND} VALUES(4, 2)"; + + #plugin implemented objects + #sqlite3 $WRT_DB "${INS_PLUGIN_OBJECTS} VALUES(1, )"; + sqlite3 $WRT_DB "${INS_PLUGIN_OBJECTS} VALUES('', 2)"; + sqlite3 $WRT_DB "${INS_PLUGIN_OBJECTS} VALUES('Plugin_3_Object_A', 3)"; + sqlite3 $WRT_DB "${INS_PLUGIN_OBJECTS} VALUES('Plugin_4_Object_A', 4)"; + sqlite3 $WRT_DB "${INS_PLUGIN_OBJECTS} VALUES('Plugin_4_Object_B', 4)"; + sqlite3 $WRT_DB "${INS_PLUGIN_OBJECTS} VALUES('Plugin_4_Object_C', 4)"; + sqlite3 $WRT_DB "${INS_PLUGIN_OBJECTS} VALUES('Plugin_5_Object_A', 5)"; + + #simple features + INS_ALL_FEATURESLIST="insert into FeaturesList(FeatureUUID, FeatureName, PluginPropertiesId)" + sqlite3 $WRT_DB "${INS_ALL_FEATURESLIST} VALUES(1, 'feature1', 1)"; + sqlite3 $WRT_DB "${INS_ALL_FEATURESLIST} VALUES(2, 'feature2', 4)"; + sqlite3 $WRT_DB "${INS_ALL_FEATURESLIST} VALUES(3, 'feature3', 4)"; + sqlite3 $WRT_DB "${INS_ALL_FEATURESLIST} VALUES(4, 'feature4', 4)"; + + #device capabilities + INS_ALL_DEVICECAPS="insert into DeviceCapabilities(DeviceCapID, DeviceCapName, DeviceCapDefaultValue)" + sqlite3 $WRT_DB "${INS_ALL_DEVICECAPS} VALUES(1, 'devicecap1', 1)"; + sqlite3 $WRT_DB "${INS_ALL_DEVICECAPS} VALUES(2, 'devicecap2', 2)"; + sqlite3 $WRT_DB "${INS_ALL_DEVICECAPS} VALUES(3, 'devicecap3', 3)"; + sqlite3 $WRT_DB "${INS_ALL_DEVICECAPS} VALUES(4, 'devicecap4', 4)"; + + #device capabilities proxy + INS_ALL_DEVICECAPSPROXY="insert into FeatureDeviceCapProxy(DeviceCapID, FeatureUUID)" + sqlite3 $WRT_DB "${INS_ALL_DEVICECAPSPROXY} VALUES(1, 1)"; + sqlite3 $WRT_DB "${INS_ALL_DEVICECAPSPROXY} VALUES(1, 2)"; + sqlite3 $WRT_DB "${INS_ALL_DEVICECAPSPROXY} VALUES(2, 2)"; + sqlite3 $WRT_DB "${INS_ALL_DEVICECAPSPROXY} VALUES(3, 3)"; + + #Widgets + INS_ALL_WIDGETEXT="insert into WidgetExtendedInfo(app_id, install_time)" + INS_ALL_WIDGET="insert into WidgetInfo(app_id, widget_id, widget_version, widget_width, widget_height, author_name, author_email, author_href, base_folder, webkit_plugins_required, wac_signed, min_version, tizen_pkgid, tizen_appid, back_supported, csp_policy_report_only)" + INS_ALL_WIDGET_LOC="insert into LocalizedWidgetInfo(app_id, widget_locale, widget_name, widget_shortname, widget_description, widget_license, widget_license_file, widget_license_href)" + INS_ALL_WIDGET_ICONS="insert into WidgetIcon(app_id, icon_src, icon_width, icon_height)" + INS_ALL_WIDGET_LOC_ICONS="insert into WidgetLocalizedIcon(app_id, icon_id, widget_locale)" + INS_ALL_WIDGET_STARTFILE="insert into WidgetStartFile(app_id, src)" + INS_ALL_WIDGET_LOC_STARTFILE="insert into WidgetLocalizedStartFile(app_id, start_file_id, widget_locale, type, encoding)" + INS_ALL_WIDGET_DEFPREF="insert into WidgetDefaultPreference(app_id, key_name, key_value, readonly)" + INS_ALL_WIDGET_PREF="insert into WidgetPreference(app_id,tizen_appid, key_name, key_value, readonly)" + INS_ALL_WIDGET_FEATURE="insert into WidgetFeature(widget_feature_id, app_id, name, rejected)" + INS_ALL_WIDGET_WINMODES="insert into WidgetWindowModes(app_id, window_mode)" + INS_ALL_WIDGET_WARP="insert into WidgetWARPInfo(app_id, iri, subdomain_access)" + INS_ALL_WIDGET_CERT="insert into WidgetCertificateFingerprint(app_id, owner, chainid, type, md5_fingerprint, sha1_fingerprint, common_name)" + INS_ALL_WIDGET_POWDERLEV="insert into PowderLevels(app_id, category, level)" + INS_ALL_WIDGET_POWDERLEV_CONT="insert into PowderLevelContexts(levelid, context)" + + + sqlite3 $WRT_DB "${INS_ALL_WIDGET} VALUES(2000, 'w_id_2000', '1.0.0', 100, 200, 'a_name_2000', 'a_email_2000', 'a_href_2000', 'basef_2000', 1, 1, '1.0', 'pkgid201', 'tizenid201', 1, 'policy_report201')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET} VALUES(2001, 'w_id_2001', '2.0.0', 100, 200, 'a_name_2001', 'a_email_2001', 'a_href_2001', 'basef_2001', 1, 1, '0.5', 'pkgid202', 'tizenid202', 0, 'policy_report202')"; + sqlite3 $WRT_DB "insert into WidgetInfo(app_id, back_supported, tizen_appid) VALUES(2002, 0, 'tizenid203')"; + sqlite3 $WRT_DB "insert into WidgetInfo(app_id, back_supported, tizen_appid) VALUES(2003, 0, 'tizenid204')"; # for properties tests + + sqlite3 $WRT_DB "${INS_ALL_WIDGETEXT} VALUES(2000, 1256)"; + sqlite3 $WRT_DB "${INS_ALL_WIDGETEXT} VALUES(2001, 5687)"; + sqlite3 $WRT_DB "insert into WidgetExtendedInfo(app_id) VALUES(2002)"; + sqlite3 $WRT_DB "insert into WidgetExtendedInfo(app_id) VALUES(2003)"; + + sqlite3 $WRT_DB "${INS_ALL_WIDGET_LOC} VALUES(2000, 'en', 'w_name_2000_en', 'w_shortname_2000_en', 'w_desc_2000_en', 'w_lic_2000_en', 'w_licf_2000_en', 'w_lic_href_2000_en')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_LOC} VALUES(2000, 'pl', 'w_name_2000_pl', 'w_shortname_2000_pl', 'w_desc_2000_pl', 'w_lic_2000_pl', 'w_licf_2000_pl', 'w_lic_href_2000_pl')"; + sqlite3 $WRT_DB "insert into LocalizedWidgetInfo(app_id, widget_locale) VALUES(2002, 'en')"; + sqlite3 $WRT_DB "insert into LocalizedWidgetInfo(app_id, widget_locale) VALUES(2003, 'en')"; + + sqlite3 $WRT_DB "${INS_ALL_WIDGET_ICONS} VALUES(2000, 'icon_src_2000', 50, 50)"; + sqlite3 $WRT_DB "insert into WidgetIcon(app_id, icon_src) VALUES(2002, 'icon_src_2002')"; + + sqlite3 $WRT_DB "${INS_ALL_WIDGET_LOC_ICONS} VALUES(2000, 1, 'en')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_LOC_ICONS} VALUES(2000, 1, 'pl')"; + + sqlite3 $WRT_DB "${INS_ALL_WIDGET_STARTFILE} VALUES(2000, 'start_file_2000')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_STARTFILE} VALUES(2001, 'start_file_2001')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_STARTFILE} VALUES(2002, 'start_file_2002')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_STARTFILE} VALUES(2003, 'start_file_2003')"; + + sqlite3 $WRT_DB "${INS_ALL_WIDGET_LOC_STARTFILE} VALUES(2000, 1, 'en', '', '')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_LOC_STARTFILE} VALUES(2001, 2, 'en', '', '')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_LOC_STARTFILE} VALUES(2002, 3, 'en', '', '')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_LOC_STARTFILE} VALUES(2003, 4, 'en', '', '')"; + + #widget properties + sqlite3 $WRT_DB "${INS_ALL_WIDGET_PREF} VALUES(2000,'tizenid201', 'key1_for_2000', 'value_for_key1_2000', 0)"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_PREF} VALUES(2000,'tizenid201', 'key2_for_2000', 'value_for_key2_2000', 0)"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_PREF} VALUES(2001,'tizenid202', 'key1_for_2001', 'value1_for_key_2001', 1)"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_PREF} VALUES(2002,'tizenid203', 'key1_for_2002', 'value1_for_key_2002', 0)"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET_PREF} VALUES(2002,'tizenid203', 'key2_for_2002', 'value2_for_key_2002', 1)"; + + sqlite3 $WRT_DB "${INS_ALL_WIDGET_FEATURE} VALUES(1, 2001, 'feature_name', 0)"; + + #create if not exists and fix autoincrement value + sqlite3 $WRT_DB "INSERT INTO WidgetInfo(tizen_appid) VALUES('temp')"; + sqlite3 $WRT_DB "DELETE FROM WidgetInfo WHERE tizen_appid = 'temp'"; + sqlite3 $WRT_DB "UPDATE sqlite_sequence SET seq = 2004 WHERE name = 'WidgetInfo'"; + + mkdir "/opt/usr/apps/testWidget123" + mkdir "/opt/usr/apps/testWidget123/data" + mkdir "/opt/usr/apps/pkgid201" + mkdir "/opt/usr/apps/pkgid201/data" + + exit $? + +elif [ "x$1" == "xstop" ]; then + echo stop; + cp $WRT_DB_BCK $WRT_DB + rm -r "/opt/usr/apps/testWidget123" + rm -r "/opt/usr/apps/pkgid201" + + exit $? +else + exit 1 +fi diff --git a/tests/db/CMakeLists.txt b/tests/db/CMakeLists.txt new file mode 100644 index 0000000..837679e --- /dev/null +++ b/tests/db/CMakeLists.txt @@ -0,0 +1,49 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Lukasz Marek (l.marek@samsung.com) +# @version 1.0 +# @brief +# + +# +# Test files +# +# Define all DPL tests sources. +# Runner is responsible for runnint it all and +# generating proper output files +# + +SET(TARGET_NAME "wrt-commons-tests-db") + +# Set DPL tests sources +SET(DPL_TESTS_DB_SOURCES + ${TESTS_DIR}/db/main.cpp + ${TESTS_DIR}/db/test_orm.cpp + ${TESTS_DIR}/db/test_sql_connection.cpp +) + +ADD_SUBDIRECTORY(orm) + +#include subdirectory +WRT_INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/orm) +WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_NAME} ${TARGET_DPL_DB_EFL}) +WRT_TEST_BUILD(${TARGET_NAME} ${DPL_TESTS_DB_SOURCES}) +WRT_TEST_INSTALL(${TARGET_NAME}) + +INSTALL(FILES + ${TESTS_DIR}/db/orm/dpl_orm_test.db + DESTINATION /opt/share/wrt/wrt-commons/tests/db +) diff --git a/tests/db/main.cpp b/tests/db/main.cpp new file mode 100644 index 0000000..4ed6191 --- /dev/null +++ b/tests/db/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file main.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main. + */ + +#include + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} diff --git a/tests/db/orm/CMakeLists.txt b/tests/db/orm/CMakeLists.txt new file mode 100644 index 0000000..b7ebafb --- /dev/null +++ b/tests/db/orm/CMakeLists.txt @@ -0,0 +1,11 @@ +WRT_INTROSPECT_TARGET(db ${TARGET_DPL_DB_EFL}) +WRT_CONVERT_TO_GCC_LIST(db_INCLUDE_DIRS_GCC ${db_INCLUDE_DIRS}) + +ADD_CUSTOM_COMMAND( OUTPUT dpl_orm_test_db.sql + COMMAND rm -f ${CMAKE_CURRENT_SOURCE_DIR}/dpl_orm_test.db + COMMAND C_INCLUDE_PATH=${db_INCLUDE_DIRS_GCC} gcc -Wall -E ${CMAKE_CURRENT_SOURCE_DIR}/dpl_orm_test_db_sql_generator.h | grep --invert-match "^#" > ${CMAKE_CURRENT_SOURCE_DIR}/dpl_orm_test_db.sql + COMMAND sqlite3 ${CMAKE_CURRENT_SOURCE_DIR}/dpl_orm_test.db ".read ${CMAKE_CURRENT_SOURCE_DIR}/dpl_orm_test_db.sql" || rm -f ${CMAKE_CURRENT_SOURCE_DIR}/dpl_orm_test.db + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dpl_orm_test_db_sql_generator.h ${CMAKE_CURRENT_SOURCE_DIR}/dpl_orm_test_db +) + +ADD_CUSTOM_TARGET( Sqlite3Db ALL DEPENDS dpl_orm_test_db.sql ) diff --git a/tests/db/orm/dpl_orm_test_db b/tests/db/orm/dpl_orm_test_db new file mode 100644 index 0000000..0d1963b --- /dev/null +++ b/tests/db/orm/dpl_orm_test_db @@ -0,0 +1,88 @@ + +CREATE_TABLE(TestTableInsert) + COLUMN(ColumnOptInt, INT,) + COLUMN(ColumnOptText, TEXT,) + COLUMN_NOT_NULL(ColumnInt, INT, DEFAULT 99) + COLUMN_NOT_NULL(ColumnInt2, INT,) + COLUMN_NOT_NULL(ColumnText, TEXT,) +CREATE_TABLE_END() + +CREATE_TABLE(TestTableDelete) + COLUMN(ColumnOptInt, INT,) + COLUMN(ColumnOptText, TEXT,) + COLUMN_NOT_NULL(ColumnInt, INT, DEFAULT 99) + COLUMN_NOT_NULL(ColumnInt2, INT,) + COLUMN_NOT_NULL(ColumnText, TEXT,) +CREATE_TABLE_END() + +SQL( + INSERT INTO TestTableDelete VALUES(1, "two", 3, 4, "five"); + INSERT INTO TestTableDelete VALUES(6, "seven", 8, 9, "ten"); + INSERT INTO TestTableDelete (ColumnInt2, ColumnText) VALUES(11, "twelve"); + INSERT INTO TestTableDelete (ColumnInt2, ColumnText) VALUES(13, "fourteen"); +) + +CREATE_TABLE(TestTable) + COLUMN(ColumnOptInt, INT,) + COLUMN(ColumnOptText, TEXT,) + COLUMN_NOT_NULL(ColumnInt, INT, DEFAULT 99) + COLUMN_NOT_NULL(ColumnInt2, INT,) + COLUMN_NOT_NULL(ColumnText, TEXT,) +CREATE_TABLE_END() + +SQL( + INSERT INTO TestTable VALUES(1, "two", 3, 4, "five"); + INSERT INTO TestTable VALUES(6, "seven", 8, 9, "ten"); + INSERT INTO TestTable (ColumnInt2, ColumnText) VALUES(11, "twelve"); + INSERT INTO TestTable (ColumnInt2, ColumnText) VALUES(13, "fourteen"); +) + +CREATE_TABLE(TestTableJoin1) + COLUMN_NOT_NULL(TestID, INT,) + COLUMN_NOT_NULL(TestText, TEXT,) + COLUMN(TestNumber, INT,) + TABLE_CONSTRAINTS( + PRIMARY KEY(TestID) + ) +CREATE_TABLE_END() + +CREATE_TABLE(TestTableJoin2) + COLUMN_NOT_NULL(TestID, INT,) + COLUMN_NOT_NULL(TestText1, TEXT,) + COLUMN_NOT_NULL(TestText2, TEXT,) + TABLE_CONSTRAINTS( + PRIMARY KEY(TestID) + ) +CREATE_TABLE_END() + +CREATE_TABLE(TestTableJoin3) + COLUMN_NOT_NULL(TestID, INT,) + COLUMN(Value3, INT,) + COLUMN(TestText33, TEXT,) + TABLE_CONSTRAINTS( + PRIMARY KEY(TestID) + ) +CREATE_TABLE_END() + +SQL( + INSERT INTO TestTableJoin1 VALUES(1, "text val 1", 111); + INSERT INTO TestTableJoin1 VALUES(2, "text val 2", 222); + INSERT INTO TestTableJoin1 VALUES(3, "text val 3", 333); + INSERT INTO TestTableJoin1 VALUES(4, "text val 4", 444); + INSERT INTO TestTableJoin1 VALUES(5, "text val 5", 555); + INSERT INTO TestTableJoin1 VALUES(6, "text val 6", 666); + + INSERT INTO TestTableJoin2 VALUES(1, "01", "text2 1"); + INSERT INTO TestTableJoin2 VALUES(2, "02", "text2 2"); + INSERT INTO TestTableJoin2 VALUES(3, "03", "text2 3"); + INSERT INTO TestTableJoin2 VALUES(4, " 4 ", "text2 4"); + INSERT INTO TestTableJoin2 VALUES(5, "*5*", "text2 5"); + INSERT INTO TestTableJoin2 VALUES(10, "6", "text2 6"); + + INSERT INTO TestTableJoin3 VALUES(1, 111, "test 1"); + INSERT INTO TestTableJoin3 VALUES(2, 111, "test 2"); + INSERT INTO TestTableJoin3 VALUES(3, 222, "test 3"); + INSERT INTO TestTableJoin3 VALUES(6, 222, "test 4"); + INSERT INTO TestTableJoin3 (TestID, TestText33) VALUES(7, "test 5"); + INSERT INTO TestTableJoin3 (TestID, TestText33) VALUES(10, "test 6"); +) diff --git a/tests/db/orm/dpl_orm_test_db_definitions b/tests/db/orm/dpl_orm_test_db_definitions new file mode 100644 index 0000000..da79427 --- /dev/null +++ b/tests/db/orm/dpl_orm_test_db_definitions @@ -0,0 +1,5 @@ +DATABASE_START(dpl_orm_test) + +#include "dpl_orm_test_db" + +DATABASE_END() diff --git a/tests/db/orm/dpl_orm_test_db_sql_generator.h b/tests/db/orm/dpl_orm_test_db_sql_generator.h new file mode 100644 index 0000000..cac41cc --- /dev/null +++ b/tests/db/orm/dpl_orm_test_db_sql_generator.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file dpl_orm_test_db_sql_generator.h + * @author Lukasz Marek (l.marek@samsung.com) + * @version 1.0 + * @brief Macro definitions for generating the SQL input file from + * database definition. + */ + +//Do not include this file directly! It is used only for SQL code generation. + +#include + +#include "dpl_orm_test_db_definitions" diff --git a/tests/db/orm/dpl_orm_test_db_sql_generator.h.gch b/tests/db/orm/dpl_orm_test_db_sql_generator.h.gch new file mode 100644 index 0000000..5bd675d Binary files /dev/null and b/tests/db/orm/dpl_orm_test_db_sql_generator.h.gch differ diff --git a/tests/db/orm/generator_dpl_orm_test.h b/tests/db/orm/generator_dpl_orm_test.h new file mode 100644 index 0000000..39bb1b7 --- /dev/null +++ b/tests/db/orm/generator_dpl_orm_test.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ORM_GENERATOR_DPL_ORM_TEST_H +#define ORM_GENERATOR_DPL_ORM_TEST_H + +#define ORM_GENERATOR_DATABASE_NAME dpl_orm_test_db_definitions +#include +#undef ORM_GENERATOR_DATABASE_NAME + +#endif diff --git a/tests/db/test_orm.cpp b/tests/db/test_orm.cpp new file mode 100644 index 0000000..c7c9ea9 --- /dev/null +++ b/tests/db/test_orm.cpp @@ -0,0 +1,1140 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include + +const char* PATH_DB = "/opt/share/wrt/wrt-commons/tests/db/dpl_orm_test.db"; + +//utils + +#define TEST_REPETITION 16 + +class SmartAttach +{ + public: + + SmartAttach(bool autoattach = true) : + m_interface(PATH_DB, + DPL::DB::SqlConnection::Flag::UseLucene), + m_autoattach(autoattach) + { + if (m_autoattach) { + m_interface.AttachToThread(DPL::DB::SqlConnection::Flag::RW); + } + } + + ~SmartAttach() + { + if (m_autoattach) { + m_interface.DetachFromThread(); + } + } + + DPL::DB::ThreadDatabaseSupport* get() + { + return &m_interface; + } + + private: + DPL::DB::ThreadDatabaseSupport m_interface; + bool m_autoattach; +}; + +template +bool ContainerContentsEqual(const ContainerType1& container1, + const ContainerType2& container2) +{ + using namespace DPL::DB::ORM::dpl_orm_test::TestTableInsert; + typedef std::set Set1; + typedef std::set Set2; + Set1 set1(container1.begin(), container1.end()); + Set2 set2(container2.begin(), container2.end()); + + for (typename Set1::iterator it = set1.begin(); + it != set1.end(); + it++) + { + LogDebug("Set1 element: " << *it); + } + + for (typename Set2::iterator it = set2.begin(); it != set2.end(); it++) { + LogDebug("Set2 element: " << *it); + } + + return set1 == set2; +} + +template +std::list makeList(const T& a, const T& b) +{ + std::list list; + list.push_back(a); + list.push_back(b); + return list; +} + +//tests + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: ORM_SelectSingleValue +Description: tests quering single value of single row from database +Expected: Values should match those which were prepared +*/ +RUNNER_TEST(ORM_SelectSingleValue) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + //Getting each column + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + int result; + RUNNER_ASSERT_MSG((result = + *select.GetSingleValue()) + == 6, "Got " << + result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + DPL::String result; + RUNNER_ASSERT_MSG((result = + *select.GetSingleValue( + )) == L"seven", + "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + int result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 8, "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + int result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 9, "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + DPL::String result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == L"ten", "Got " << result); + } + + //Where on each column + { + TestTable::Select select(interface.get()); + select.Where(Equals(6)); + int result; + RUNNER_ASSERT_MSG((result = + *select.GetSingleValue()) + == 6, "Got " << + result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(DPL::String(L"seven"))); + DPL::String result; + RUNNER_ASSERT_MSG((result = + *select.GetSingleValue( + )) == L"seven", + "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(8)); + int result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 8, "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(9)); + int result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 9, "Got " << result); + } + { + TestTable::Select select(interface.get()); + select.Where(Equals(L"ten")); + DPL::String result; + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == L"ten", "Got " << result); + } +} + +/* +Name: ORM_SelectSingleRow +Description: tests quering single row from database +Expected: Values should match those which were prepared +*/ +RUNNER_TEST(ORM_SelectSingleRow) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + { + TestTable::Select select(interface.get()); + select.Where(Equals(3)); + TestTable::Row result = select.GetSingleRow(); + TestTable::Row expected; + expected.Set_ColumnOptInt(1); + expected.Set_ColumnOptText(DPL::String(L"two")); + expected.Set_ColumnInt(3); + expected.Set_ColumnInt2(4); + expected.Set_ColumnText(L"five"); + RUNNER_ASSERT_MSG(result == expected, "Got " << result); + } + + { + TestTable::Select select(interface.get()); + select.Where(Equals(DPL::String(L"seven"))); + TestTable::Row result = select.GetSingleRow(); + TestTable::Row expected; + expected.Set_ColumnOptInt(6); + expected.Set_ColumnOptText(DPL::String(L"seven")); + expected.Set_ColumnInt(8); + expected.Set_ColumnInt2(9); + expected.Set_ColumnText(L"ten"); + RUNNER_ASSERT_MSG(result == expected, "Got " << result); + } +} + +/* +Name: ORM_SelectRowList +Description: tests quering multiple row from database +Expected: Values should match those which were prepared +*/ +RUNNER_TEST(ORM_SelectRowList) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + { + TestTable::Select select(interface.get()); + select.Where(Equals(3)); + std::list result = select.GetRowList(); + RUNNER_ASSERT_MSG(result.size() == 1, "Got " << result.size()); + + TestTable::Row expected; + expected.Set_ColumnOptInt(1); + expected.Set_ColumnOptText(DPL::String(L"two")); + expected.Set_ColumnInt(3); + expected.Set_ColumnInt2(4); + expected.Set_ColumnText(L"five"); + RUNNER_ASSERT_MSG(*(result.begin()) == expected, "Got " << + *(result.begin()) ); + } + + { + TestTable::Select select(interface.get()); + select.Where(Equals(DPL::String(L"seven"))); + std::list result = select.GetRowList(); + RUNNER_ASSERT_MSG(result.size() == 1, "Got " << result.size()); + + TestTable::Row expected; + expected.Set_ColumnOptInt(6); + expected.Set_ColumnOptText(DPL::String(L"seven")); + expected.Set_ColumnInt(8); + expected.Set_ColumnInt2(9); + expected.Set_ColumnText(L"ten"); + RUNNER_ASSERT_MSG(*(result.begin()) == expected, "Got " << + *(result.begin()) ); + } + + { + TestTable::Select select(interface.get()); + select.Where(Equals(99)); + std::list result = select.GetRowList(); + + TestTable::Row expected1; + expected1.Set_ColumnInt(99); + expected1.Set_ColumnInt2(11); + expected1.Set_ColumnText(L"twelve"); + + TestTable::Row expected2; + expected2.Set_ColumnInt(99); + expected2.Set_ColumnInt2(13); + expected2.Set_ColumnText(L"fourteen"); + + RUNNER_ASSERT(ContainerContentsEqual(makeList(expected1, + expected2), result)); + } +} + +/* +Name: ORM_SelectValueList +Description: tests quering single column from multiple row from database +Expected: Values should match those which were prepared +*/ +RUNNER_TEST(ORM_SelectValueList) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + //Getting each column + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(99, 99))); + } + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(11, 13))); + } + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(DPL::String(L"twelve"), + DPL::String(L"fourteen")))); + } + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(DPL::Optional + ::Null, + DPL::Optional + ::Null))); + } + + //Where on each column + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional::Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(11, 13))); + } + { + TestTable::Select select(interface.get()); + select.Where(Is(DPL::Optional:: + Null)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(11, 13))); + } + { + TestTable::Select select(interface.get()); + select.Where(Is(99)); + RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList(), + makeList(11, 13))); + } +} + +/* +Name: ORM_MultipleCalls +Description: tests sequnece of different queries +Expected: Values should match those which were prepared +*/ +RUNNER_TEST(ORM_MultipleCalls) +{ + for (int j = 0; j < TEST_REPETITION; j++) { + for (int i = 0; i < TEST_REPETITION; i++) { + ORM_SelectSingleValue(); + } + + for (int i = 0; i < TEST_REPETITION; i++) { + ORM_SelectSingleRow(); + } + + for (int i = 0; i < TEST_REPETITION; i++) { + ORM_SelectRowList(); + } + + for (int i = 0; i < TEST_REPETITION; i++) { + ORM_SelectValueList(); + } + } +} + +/* +Name: ORM_Insert +Description: tests insering rows into database +Expected: Values should be inserted +*/ +RUNNER_TEST(ORM_Insert) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + + TestTableInsert::Select select1(interface.get()); + std::list resultList = select1.GetValueList(); + RUNNER_ASSERT_MSG(resultList.empty(), + "Returned list has wrong size: " << resultList.size()); + + std::list list; + + TestTableInsert::Insert insert(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnOptInt(1); + row.Set_ColumnInt2(2); + row.Set_ColumnText(L"three"); + insert.Values(row); + insert.Execute(); + + row.Set_ColumnInt(99); + list.push_back(row); + { + TestTableInsert::Select select2(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select2.GetRowList(), + list), "Returned list doesn't match."); + } + + TestTableInsert::Insert insert2(interface.get()); + TestTableInsert::Row row2; + row2.Set_ColumnInt(4); + row2.Set_ColumnInt2(5); + row2.Set_ColumnText(L"six"); + insert2.Values(row2); + insert2.Execute(); + + list.push_back(row2); + { + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + list), "Returned list doesn't match."); + } + + TestTableInsert::Insert insert3(interface.get()); + TestTableInsert::Row row3; + row3.Set_ColumnOptInt(1); + row3.Set_ColumnInt2(7); + row3.Set_ColumnText(L"eight"); + insert3.Values(row3); + insert3.Execute(); + + row3.Set_ColumnInt(99); + list.push_back(row3); + { + TestTableInsert::Select select3(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select3.GetRowList(), + list), "Returned list doesn't match."); + } + + TestTableInsert::Insert insert4(interface.get()); + TestTableInsert::Row row4; + row4.Set_ColumnOptInt(9); + row4.Set_ColumnInt2(10); + row4.Set_ColumnText(L"eleven"); + insert4.Values(row4); + insert4.Execute(); + + row4.Set_ColumnInt(99); + list.push_back(row4); + { + TestTableInsert::Select select4(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select4.GetRowList(), + list), "Returned list doesn't match."); + } + + // restore original table state + { + TestTableInsert::Delete del(interface.get()); + del.Execute(); + + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT(select.GetRowList().size() == 0); + } +} + +/* +Name: ORM_MultipleBindInsert +Description: repeats ORM_Insert test several times +Expected: Values should be inserted +*/ +RUNNER_TEST(ORM_MultipleBindInsert) +{ + for (int i = 0; i < TEST_REPETITION; i++) { + ORM_Insert(); + } +} + +/* +Name: ORM_Delete +Description: tests deleting rows from database +Expected: deleted rows should not exist +*/ +RUNNER_TEST(ORM_Delete) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + TestTableDelete::Select selectStart(interface.get()); + selectStart.OrderBy(DPL::TypeListDecl >()); + std::list list = selectStart.GetRowList(); + std::list originalList = list; + + std::vector vector(list.begin(), list.end()); + RUNNER_ASSERT_MSG( + list.size() == 4, "Returned list has wrong size: " << list.size()); + + typedef DPL::String S; + + //no-act deletes + { + TestTableDelete::Delete del(interface.get()); + del.Where(And(Equals(1), + Equals(S(L"seven")))); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + list), "Returned list doesn't match."); + } + + { + TestTableDelete::Delete del(interface.get()); + del.Where(And(Equals(6), + Equals(S(L"two")))); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + list), "Returned list doesn't match."); + } + + { + TestTableDelete::Delete del(interface.get()); + del.Where(Equals(10)); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + list), "Returned list doesn't match."); + } + + //act deletes + { + list.remove(vector[1]); + + TestTableDelete::Delete del(interface.get()); + del.Where(And(Equals(6), + Equals(L"ten"))); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + list), "Returned list doesn't match."); + } + + { + list.remove(vector[2]); + list.remove(vector[3]); + + TestTableDelete::Delete del(interface.get()); + del.Where(Is(DPL::Optional + ::Null)); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + list), "Returned list doesn't match."); + } + + { + TestTableDelete::Delete del(interface.get()); + del.Execute(); + + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG( + select.GetRowList().size() == 0, "Returned list is not empty"); + } + + // Restore original table state + // This also tests if multiple different binds for Insert are working + // properly + for (std::list::iterator i = originalList.begin(); + i != originalList.end(); + ++i) + { + TestTableDelete::Insert insert(interface.get()); + insert.Values(*i); + insert.Execute(); + } + + { + TestTableDelete::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + originalList), + "Returned list doesn't match."); + } +} + +/* +Name: ORM_MultipleBindDelete +Description: repeats ORM_Delete test several times +Expected: Values should be deleted +*/ +RUNNER_TEST(ORM_MultipleBindDelete) +{ + for (int i = 0; i < TEST_REPETITION; i++) { + ORM_Delete(); + } +} + +/* +Name: ORM_MultipleBindWhere +Description: tests if multiple bind of same query obejct works +Expected: Each bind and execution of query should be correct +*/ +RUNNER_TEST(ORM_MultipleBindWhere) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + { + TestTable::Select select(interface.get()); + int result; + select.Where(Equals(8)); + RUNNER_ASSERT_MSG((result = + *select.GetSingleValue()) + == 6, "Got " << + result); + + select.Where(Equals(3)); + RUNNER_ASSERT_MSG((result = + *select.GetSingleValue()) + == 1, "Got " << + result); + + select.Where(Equals(8)); + RUNNER_ASSERT_MSG((result = + *select.GetSingleValue()) + == 6, "Got " << + result); + + select.Where(Equals(3)); + RUNNER_ASSERT_MSG((result = + *select.GetSingleValue()) + == 1, "Got " << + result); + } + + { + TestTable::Select select(interface.get()); + int result; + select.Where(And(Equals(99), + Equals(L"fourteen"))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 13, "Got " << result); + + select.Where(And(Equals(99), + Equals(L"twelve"))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 11, "Got " << result); + + select.Where(And(Equals(99), + Equals(L"fourteen"))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 13, "Got " << result); + + select.Where(And(Equals(99), + Equals(L"twelve"))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 11, "Got " << result); + } + + { + TestTable::Select select(interface.get()); + int result; + select.Where(And(Equals(L"fourteen"), + Equals(99))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 13, "Got " << result); + + select.Where(And(Equals(L"twelve"), + Equals(99))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 11, "Got " << result); + + select.Where(And(Equals(L"fourteen"), + Equals(99))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 13, "Got " << result); + + select.Where(And(Equals(L"twelve"), + Equals(99))); + RUNNER_ASSERT_MSG((result = select.GetSingleValue( + )) == 11, "Got " << result); + } +} + +/* +Name: ORM_Update +Description: tests rows update in database +Expected: Successful update +*/ +RUNNER_TEST(ORM_Update) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + + std::list list; + + TestTableInsert::Delete del(interface.get()); + del.Execute(); + + // INSERT + { + TestTableInsert::Insert insert(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnOptInt(5); + row.Set_ColumnInt2(2); + row.Set_ColumnText(L"two"); + insert.Values(row); + insert.Execute(); + + row.Set_ColumnInt(99); + list.push_back(row); + } + { + TestTableInsert::Insert insert(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnOptInt(1); + row.Set_ColumnInt2(2); + row.Set_ColumnText(L"three"); + insert.Values(row); + insert.Execute(); + + row.Set_ColumnInt(99); + list.push_back(row); + } + { + TestTableInsert::Insert insert(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnOptInt(2); + row.Set_ColumnInt2(3); + row.Set_ColumnText(L"three"); + insert.Values(row); + insert.Execute(); + + row.Set_ColumnInt(99); + list.push_back(row); + + // CHECK + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + list), "Returned list doesn't match."); + } + { + // UPDATE - no rows + TestTableInsert::Update update(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnInt2(4); + row.Set_ColumnText(L"four"); + update.Values(row); + update.Where(Equals(12)); + update.Execute(); + + // CHECK + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + list), "Returned list doesn't match."); + } + { + // UPDATE - one row + TestTableInsert::Update update(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnInt2(2); + row.Set_ColumnText(L"four"); + update.Values(row); + update.Where(Equals(3)); + update.Execute(); + + list.back().Set_ColumnInt2(2); + list.back().Set_ColumnText(L"four"); + + // CHECK + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + list), "Returned list doesn't match."); + } + + { + // UPDATE - multiple rows + TestTableInsert::Update update(interface.get()); + TestTableInsert::Row row; + row.Set_ColumnText(L"dup"); + update.Values(row); + update.Where(Equals(2)); + update.Execute(); + + FOREACH(it, list) + { + it->Set_ColumnText(L"dup"); + } + + // CHECK + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT_MSG(ContainerContentsEqual( + select.GetRowList(), + list), "Returned list doesn't match."); + } + + // restore original table state + { + TestTableInsert::Delete del2(interface.get()); + del2.Execute(); + + TestTableInsert::Select select(interface.get()); + RUNNER_ASSERT(select.GetRowList().size() == 0); + } +} + +/* +Name: ORM_MultipleBindUpdate +Description: repeats ORM_Update severl times +Expected: Successful update +*/ +RUNNER_TEST(ORM_MultipleBindUpdate) +{ + for (int i = 0; i < TEST_REPETITION; i++) { + ORM_Update(); + } +} + +/* +Name: ORM_transactions +Description: checks creation of transation object +Expected: Successful creation of transaction object +*/ +RUNNER_TEST(ORM_transactions) +{ + SmartAttach interface; + DPL::DB::ORM::dpl_orm_test::ScopedTransaction transaction(interface.get()); +} + +/* +Name: ORM_MultiAttach +Description: checks correct behaviou in case of multiple tries to attach to database +Expected: Methods attaching/dettaching should be prepared for multiple calling +*/ +RUNNER_TEST(ORM_MultiAttach) +{ + SmartAttach interface(false); + RUNNER_ASSERT_MSG( + !interface.get()->IsAttached(), "Is attached, but shouldn't be."); + interface.get()->AttachToThread(); + RUNNER_ASSERT_MSG( + interface.get()->IsAttached(), "Isn't attached, but should be."); + interface.get()->AttachToThread(); + RUNNER_ASSERT_MSG( + interface.get()->IsAttached(), "Isn't attached, but should be."); + interface.get()->DetachFromThread(); + RUNNER_ASSERT_MSG( + interface.get()->IsAttached(), "Isn't attached, but should be."); + interface.get()->DetachFromThread(); + RUNNER_ASSERT_MSG( + !interface.get()->IsAttached(), "Is attached, but shouldn't be."); +} + +/* +Name: ORM_Join +Description: tests ORM's join operation +Expected: values should insist correct join operation +*/ +RUNNER_TEST(ORM_Join) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + + typedef DPL::TypeListDecl::Type JoinColumns; + + /* Test for correct join: + * 5 ids from first table matches 5 ids from second table thus join result + * contains 5 rows */ + TestTableJoin1::Select select(interface.get()); + select.Join(Equal()); + std::list > rowlist = + select.GetCustomRowList >(); + + RUNNER_ASSERT_MSG( + rowlist.size() == 5, "Invalid number of rows fetched: " << rowlist.size()); + + std::string text; + std::ostringstream oss; + int cnt = 0; + FOREACH(rowit, rowlist) + { + cnt++; + + text = + DPL::ToUTF8String((*rowit).GetColumnData()); + oss << "text val " << cnt; + RUNNER_ASSERT_MSG(text.compare( + oss.str()) == 0, + "Invalid value from first column: " + << text << " expected: " << oss.str()); + oss.str(std::string()); + + text = + DPL::ToUTF8String((*rowit).GetColumnData()); + oss << "text2 " << cnt; + RUNNER_ASSERT_MSG(text.compare( + oss.str()) == 0, + "Invalid value from second column: " + << text << " expected: " << oss.str()); + oss.str(std::string()); + } + /* Test for empty join: + * None of number values from first table matches ids from second table + * - join result should be empty */ + TestTableJoin1::Select select2(interface.get()); + select2.Join(Equal()); + rowlist = select2.GetCustomRowList >(); + + RUNNER_ASSERT_MSG(rowlist.empty(), "Result should be empty but it is not!"); + + /* Test for "converted" join: + * - join made with int column and text column as keys + * - expected 5 matching rows (one row of 6 should not be matched)*/ + TestTableJoin1::Select select3(interface.get()); + select3.Join(Equal()); + rowlist = select3.GetCustomRowList >(); + RUNNER_ASSERT_MSG( + rowlist.size() == 5, "Expected 5 rows while received: " << rowlist.size()); + cnt = 0; + FOREACH(rowit, rowlist) + { + cnt++; + // look at last two insertions into TestTableJoin2 + // for this skip understanding + if (cnt == 5) { + cnt = 6; + } + text = + DPL::ToUTF8String((*rowit).GetColumnData()); + oss << "text val " << cnt; + RUNNER_ASSERT_MSG(text.compare( + oss.str()) == 0, + "Invalid value from first column: " + << text << " expected: " << oss.str() << + " iteration: " << cnt); + oss.str(std::string()); + + text = + DPL::ToUTF8String((*rowit).GetColumnData()); + oss << "text2 " << cnt; + RUNNER_ASSERT_MSG(text.compare( + oss.str()) == 0, + "Invalid value from second column: " + << text << " expected: " << oss.str() << + " iteration: " << cnt); + oss.str(std::string()); + } + + /* Test for join with non-unique nullable columns given as keys*/ + typedef DPL::TypeListDecl::Type JoinTables2; + TestTableJoin1::Select select4(interface.get()); + select4.Join(Equal()); + std::list > rowlist2 = + select4.GetCustomRowList >(); + RUNNER_ASSERT_MSG( + rowlist2.size() == 4, "Expected 4 rows while received: " << + rowlist.size()); + cnt = 0; + DPL::Optional optext; + FOREACH(rowit, rowlist2) + { + cnt++; + + text = + DPL::ToUTF8String((*rowit).GetColumnData()); + // values expected in subsequent (1,2,3,4) iterations: 1 1 2 2 + oss << "text val " << (1 + (int)(cnt / 3)); + RUNNER_ASSERT_MSG(text.compare( + oss.str()) == 0, + "Invalid value from first column: " + << text << " expected: " << oss.str() << + " iteration: " << cnt); + oss.str(std::string()); + + optext = (*rowit).GetColumnData(); + text = DPL::ToUTF8String(*optext); + oss << "test " << cnt; + RUNNER_ASSERT_MSG(text.compare( + oss.str()) == 0, + "Invalid value from second column: " + << text << " expected: " << oss.str() << + " iteration: " << cnt); + oss.str(std::string()); + } + + /* Test for join made on three tables: + * - 3 text columns selected for join + * - Equal made for TestID of (table1 and table2) and (table1 and table3) */ + typedef DPL::TypeListDecl::Type Join3Tables; + TestTableJoin1::Select select5(interface.get()); + select5.Join(Equal()); + select5.Join(Equal()); + std::list > rowlist3tab = + select5.GetCustomRowList >(); + RUNNER_ASSERT_MSG( + rowlist3tab.size() == 3, "Expected 3 rows while received: " << + rowlist3tab.size()); + cnt = 0; + FOREACH(rowit, rowlist3tab) + { + cnt++; + + text = + DPL::ToUTF8String((*rowit).GetColumnData()); + oss << "text val " << cnt; + RUNNER_ASSERT_MSG(text.compare( + oss.str()) == 0, + "Invalid value from first column: " + << text << " expected: " << oss.str() << + " iteration: " << cnt); + oss.str(std::string()); + + text = + DPL::ToUTF8String((*rowit).GetColumnData()); + oss << "text2 " << cnt; + RUNNER_ASSERT_MSG(text.compare( + oss.str()) == 0, + "Invalid value from first column: " + << text << " expected: " << oss.str() << + " iteration: " << cnt); + oss.str(std::string()); + + optext = (*rowit).GetColumnData(); + text = DPL::ToUTF8String(*optext); + oss << "test " << cnt; + RUNNER_ASSERT_MSG(text.compare( + oss.str()) == 0, + "Invalid value from second column: " + << text << " expected: " << oss.str() << + " iteration: " << cnt); + oss.str(std::string()); + } +} + +RUNNER_TEST(ORM_SelectOrderByMultipleColumns) +{ + SmartAttach interface; + using namespace DPL::DB::ORM; + using namespace DPL::DB::ORM::dpl_orm_test; + { + TestTableJoin3::Select select(interface.get()); + + // testing: " ORDER BY Value3 ASC, TestID DESC, TestID ASC" + select.OrderBy(DPL::TypeListDecl, + OrderingDescending, + OrderingAscending >()); + + std::list result = select.GetRowList(); + std::list::const_iterator iter = result.begin(); + { //1 row + RUNNER_ASSERT_MSG(*iter->Get_TestText33() == + DPL::FromASCIIString( + "test 6"), "Wrong row 1 order"); + RUNNER_ASSERT_MSG(iter->Get_TestID() == 10, "Wrong row 1 order"); + ++iter; + } + { //2 row + RUNNER_ASSERT_MSG(*iter->Get_TestText33() == + DPL::FromASCIIString( + "test 5"), "Wrong row 2 order"); + RUNNER_ASSERT_MSG(iter->Get_TestID() == 7, "Wrong row 2 order"); + ++iter; + } + { //3 row + RUNNER_ASSERT_MSG(iter->Get_Value3() == 111, "Wrong row 3 order"); + RUNNER_ASSERT_MSG(*iter->Get_TestText33() == + DPL::FromASCIIString( + "test 2"), "Wrong row 3 order"); + RUNNER_ASSERT_MSG(iter->Get_TestID() == 2, "Wrong row 3 order"); + ++iter; + } + { //4 row + RUNNER_ASSERT_MSG(iter->Get_Value3() == 111, "Wrong row 4 order"); + RUNNER_ASSERT_MSG(*iter->Get_TestText33() == + DPL::FromASCIIString( + "test 1"), "Wrong row 4 order"); + RUNNER_ASSERT_MSG(iter->Get_TestID() == 1, "Wrong row 4 order"); + ++iter; + } + { //5 row + RUNNER_ASSERT_MSG(iter->Get_Value3() == 222, "Wrong row 5 order"); + RUNNER_ASSERT_MSG(*iter->Get_TestText33() == + DPL::FromASCIIString( + "test 4"), "Wrong row 5 order"); + RUNNER_ASSERT_MSG(iter->Get_TestID() == 6, "Wrong row 5 order"); + ++iter; + } + { //6 row + RUNNER_ASSERT_MSG(iter->Get_Value3() == 222, "Wrong row 6 order"); + RUNNER_ASSERT_MSG(*iter->Get_TestText33() == + DPL::FromASCIIString( + "test 3"), "Wrong row 6 order"); + RUNNER_ASSERT_MSG(iter->Get_TestID() == 3, "Wrong row 6 order"); + ++iter; + } + } +} diff --git a/tests/db/test_sql_connection.cpp b/tests/db/test_sql_connection.cpp new file mode 100644 index 0000000..20907fa --- /dev/null +++ b/tests/db/test_sql_connection.cpp @@ -0,0 +1,490 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_sql_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of sql connection tests + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern const char* PATH_DB; + +RUNNER_TEST_GROUP_INIT(DPL) + +class AbstractSynchronizationObjectGenerator +{ + public: + virtual ~AbstractSynchronizationObjectGenerator() {} + + virtual DPL::DB::SqlConnection::SynchronizationObject *Create() = 0; +}; + +class NaiveSynchronizationObjectGenerator : + public AbstractSynchronizationObjectGenerator +{ + public: + virtual DPL::DB::SqlConnection::SynchronizationObject *Create() + { + return new DPL::DB::NaiveSynchronizationObject(); + } +}; + +void MassiveReadWriteTest(AbstractSynchronizationObjectGenerator *generator); + +class StressGenerator : + public DPL::Thread +{ + private: + size_t m_prefix; + std::string m_dbFileName; + AbstractSynchronizationObjectGenerator *m_generator; + + protected: + virtual int ThreadEntry() + { + DPL::DB::SqlConnection connection( + m_dbFileName, + DPL::DB::SqlConnection::Flag::None, + DPL::DB::SqlConnection::Flag::RW, + m_generator->Create()); + + DPL::DB::SqlConnection::DataCommandAutoPtr countCommand = + connection.PrepareDataCommand( + "SELECT COUNT(*) FROM test WHERE value=?"); + + for (size_t i = 0; i < 10; ++i) { + std::ostringstream valueStream; + + valueStream << "value_"; + valueStream << static_cast(m_prefix); + valueStream << "_"; + valueStream << static_cast(i); + + std::string value = valueStream.str(); + + connection.ExecCommand( + "INSERT INTO test VALUES ('%s');", + value.c_str()); + + countCommand->BindString(1, value.c_str()); + + RUNNER_ASSERT(countCommand->Step()); + + RUNNER_ASSERT(countCommand->GetColumnString(0) == "1"); + + countCommand->Reset(); + } + + countCommand.reset(); + + return 0; + } + + public: + StressGenerator(size_t prefix, + const std::string &dbFileName, + AbstractSynchronizationObjectGenerator *generator) : + m_prefix(prefix), + m_dbFileName(dbFileName), + m_generator(generator) + {} +}; + +typedef std::shared_ptr ThreadPtr; + +void MassiveReadWriteTest(AbstractSynchronizationObjectGenerator *generator) +{ + DPL::DB::SqlConnection connection(PATH_DB, + DPL::DB::SqlConnection::Flag::UseLucene, + DPL::DB::SqlConnection::Flag::RW); + + connection.ExecCommand("CREATE TABLE test(value TEXT);"); + + const size_t STRESS_GENERATOR_COUNT = 5; + ThreadPtr stressGenerators[STRESS_GENERATOR_COUNT]; + + for (size_t i = 0; i < STRESS_GENERATOR_COUNT; ++i) { + stressGenerators[i].reset( + new StressGenerator(i, PATH_DB, generator)); + + stressGenerators[i]->Run(); + } + + for (size_t i = 0; i < STRESS_GENERATOR_COUNT; ++i) { + stressGenerators[i]->Quit(); + } + + connection.ExecCommand("DROP TABLE test;"); +} + +/* +Name: SqlConnection_MassiveReadWrite_NaiveSynchronization +Description: tests massive multiple quiries from many threads +Expected: no ORM/db failures +*/ +RUNNER_TEST(SqlConnection_MassiveReadWrite_NaiveSynchronization) +{ + srand(time(NULL)); + + NaiveSynchronizationObjectGenerator m_generator; + MassiveReadWriteTest(&m_generator); +} + +/* +Name: SqlConnection_Not_Connected_Lucene +Description: tests connection to not existing database with Lucene option +Expected: exception throw +*/ +RUNNER_TEST(SqlConnection_Not_Connected_Lucene) +{ + Try { + DPL::DB::SqlConnection connection( + "/notexisitingdirectiory/foo", + DPL::DB::SqlConnection::Flag:: + UseLucene, + DPL::DB::SqlConnection::Flag::RW); + RUNNER_ASSERT_MSG(false, + "connection should throw on accessing " + "nonexistent file as a database"); + } + Catch(DPL::DB::SqlConnection::Exception::ConnectionBroken) + { + RUNNER_ASSERT(true); + } catch (DPL::Exception) { + RUNNER_ASSERT_MSG(false, "Wrong exception found"); + } +} + +/* +Name: SqlConnection_Not_Connected +Description: tests connection to not existing database without Lucene option +Expected: exception throw +*/ +RUNNER_TEST(SqlConnection_Not_Connected) +{ + Try { + DPL::DB::SqlConnection connection("/notexisitingdirectiory/foo", + DPL::DB::SqlConnection::Flag::None, + DPL::DB::SqlConnection::Flag::RW); + RUNNER_ASSERT_MSG(false, + "connection should throw on accessing " + "nonexistent file as a database"); + } + Catch(DPL::DB::SqlConnection::Exception::ConnectionBroken) + { + RUNNER_ASSERT(true); + } catch (DPL::Exception) { + RUNNER_ASSERT_MSG(false, "Wrong exception found"); + } +} + +/* +Name: SqlConnection_Null_Query +Description: tests resistance to passing NULL as query in ExecCommand +Expected: exception throw +*/ +RUNNER_TEST(SqlConnection_Null_Query) +{ + DPL::DB::SqlConnection connection(PATH_DB, + DPL::DB::SqlConnection::Flag::UseLucene, + DPL::DB::SqlConnection::Flag::RW); + Try + { + connection.ExecCommand(NULL); + RUNNER_ASSERT_MSG(false, + "Null pointer should not be accepted"); + } + Catch(DPL::DB::SqlConnection::Exception::SyntaxError) + { + RUNNER_ASSERT(true); + } catch (DPL::Exception) { + RUNNER_ASSERT_MSG(false, "Wrong exception found"); + } +} + +/* +Name: SqlConnection_Bad_Query +Description: tests resistance to passing trash as query in ExecCommand +Expected: exception throw +*/ +RUNNER_TEST(SqlConnection_Bad_Query) +{ + DPL::DB::SqlConnection connection(PATH_DB, + DPL::DB::SqlConnection::Flag::UseLucene, + DPL::DB::SqlConnection::Flag::RW); + Try + { + connection.ExecCommand("Some stupid string"); + RUNNER_ASSERT_MSG(false, "This string should not be accepted"); + } + Catch(DPL::DB::SqlConnection::Exception::SyntaxError) + { + RUNNER_ASSERT(true); + } catch (DPL::Exception) { + RUNNER_ASSERT_MSG(false, "Wrong exception found"); + } +} + +/* +Name: SqlConnection_IsNull +Description: tests IsColumnNull function +Expected: Function returns correct values +*/ +RUNNER_TEST(SqlConnection_IsNull) +{ + DPL::DB::SqlConnection connection(PATH_DB, DPL::DB::SqlConnection::Flag::UseLucene, + DPL::DB::SqlConnection::Flag::RW); + + connection.ExecCommand("CREATE TABLE testNull(value INT8);"); + + connection.ExecCommand("INSERT INTO testNull VALUES (NULL);"); + connection.ExecCommand("INSERT INTO testNull VALUES (0);"); + + DPL::DB::SqlConnection::DataCommandAutoPtr selectCommand = connection.PrepareDataCommand( + "SELECT value FROM testNull"); + + RUNNER_ASSERT(selectCommand->Step()); + RUNNER_ASSERT(selectCommand->IsColumnNull(0)); + RUNNER_ASSERT(selectCommand->Step()); + RUNNER_ASSERT(!selectCommand->IsColumnNull(0)); + selectCommand->Reset(); + + connection.ExecCommand("DROP TABLE testNull;"); +} + +/* +Name: SqlConnection_Int8 +Description: tests bind and getColumn functions for Int8 +Expected: Functions returns correct values +*/ +RUNNER_TEST(SqlConnection_Int8) +{ + DPL::DB::SqlConnection connection(PATH_DB, DPL::DB::SqlConnection::Flag::UseLucene, + DPL::DB::SqlConnection::Flag::RW); + + connection.ExecCommand("CREATE TABLE testInt8(value INT8);"); + + DPL::DB::SqlConnection::DataCommandAutoPtr insertCommand = connection.PrepareDataCommand( + "INSERT INTO testInt8 VALUES (?)"); + + DPL::DB::SqlConnection::DataCommandAutoPtr selectCommand = connection.PrepareDataCommand( + "SELECT value FROM testInt8"); + + insertCommand->BindInt8(1, 127); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + insertCommand->BindInt8(1, DPL::Optional(-127)); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + RUNNER_ASSERT(selectCommand->Step()); + RUNNER_ASSERT(selectCommand->GetColumnInt8(0) == 127); + RUNNER_ASSERT(selectCommand->Step()); + RUNNER_ASSERT(selectCommand->GetColumnOptionalInt8(0) == -127); + selectCommand->Reset(); + + connection.ExecCommand("DROP TABLE testInt8;"); +} + +/* +Name: SqlConnection_Int16 +Description: tests bind and getColumn functions for Int16 +Expected: Functions returns correct values +*/ +RUNNER_TEST(SqlConnection_Int16) +{ + DPL::DB::SqlConnection connection(PATH_DB, DPL::DB::SqlConnection::Flag::UseLucene, + DPL::DB::SqlConnection::Flag::RW); + + connection.ExecCommand("CREATE TABLE testInt16(value INT16);"); + + DPL::DB::SqlConnection::DataCommandAutoPtr insertCommand = connection.PrepareDataCommand( + "INSERT INTO testInt16 VALUES (?)"); + + DPL::DB::SqlConnection::DataCommandAutoPtr selectCommand = connection.PrepareDataCommand( + "SELECT value FROM testInt16"); + + insertCommand->BindInt16(1, (int16_t)0xFFFF); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + insertCommand->BindInt16(1, DPL::Optional((int16_t)0x8000)); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + RUNNER_ASSERT(selectCommand->Step()); + RUNNER_ASSERT(selectCommand->GetColumnInt16(0) == (int16_t)0xFFFF); + RUNNER_ASSERT(selectCommand->Step()); + RUNNER_ASSERT(selectCommand->GetColumnOptionalInt16(0) == (int16_t)0x8000); + selectCommand->Reset(); + + connection.ExecCommand("DROP TABLE testInt16;"); +} + +/* +Name: SqlConnection_Int32 +Description: tests bind and getColumn functions for Int32 +Expected: Functions returns correct values +*/ +RUNNER_TEST(SqlConnection_Int32) +{ + DPL::DB::SqlConnection connection(PATH_DB, DPL::DB::SqlConnection::Flag::UseLucene, + DPL::DB::SqlConnection::Flag::RW); + + connection.ExecCommand("CREATE TABLE testInt32(value INT32);"); + + DPL::DB::SqlConnection::DataCommandAutoPtr insertCommand = connection.PrepareDataCommand( + "INSERT INTO testInt32 VALUES (?)"); + + DPL::DB::SqlConnection::DataCommandAutoPtr selectCommand = connection.PrepareDataCommand( + "SELECT value FROM testInt32"); + + insertCommand->BindInt32(1, 0xFFFFFFFF); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + insertCommand->BindInt32(1, DPL::Optional(0x80000000)); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + RUNNER_ASSERT(selectCommand->Step()); + RUNNER_ASSERT(selectCommand->GetColumnInt32(0) == (int32_t)0xFFFFFFFF); + RUNNER_ASSERT(selectCommand->Step()); + RUNNER_ASSERT(selectCommand->GetColumnOptionalInt32(0) == 0x80000000); + selectCommand->Reset(); + + connection.ExecCommand("DROP TABLE testInt32;"); +} + +/* +Name: SqlConnection_Int64 +Description: tests bind and getColumn functions for Int64 +Expected: Functions returns correct values +*/ +RUNNER_TEST(SqlConnection_Int64) +{ + DPL::DB::SqlConnection connection(PATH_DB, DPL::DB::SqlConnection::Flag::UseLucene, + DPL::DB::SqlConnection::Flag::RW); + + connection.ExecCommand("CREATE TABLE testInt64(value INT64);"); + + DPL::DB::SqlConnection::DataCommandAutoPtr insertCommand = connection.PrepareDataCommand( + "INSERT INTO testInt64 VALUES (?)"); + + DPL::DB::SqlConnection::DataCommandAutoPtr selectCommand = connection.PrepareDataCommand( + "SELECT value FROM testInt64"); + + insertCommand->BindInt64(1, 0xFFFFFFFFFFFFFFFF); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + insertCommand->BindInt64(1, DPL::Optional(0x8000000000000000)); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + + RUNNER_ASSERT(selectCommand->Step()); + RUNNER_ASSERT(selectCommand->GetColumnInt64(0) == (int64_t)0xFFFFFFFFFFFFFFFF); + RUNNER_ASSERT(selectCommand->Step()); + RUNNER_ASSERT(selectCommand->GetColumnOptionalInt64(0) == 0x8000000000000000); + selectCommand->Reset(); + + connection.ExecCommand("DROP TABLE testInt64;"); +} + +/* +Name: SqlConnection_Float +Description: tests bind and getColumn functions for float +Expected: Functions returns correct values +*/ +RUNNER_TEST(SqlConnection_Float) +{ + DPL::DB::SqlConnection connection(PATH_DB, DPL::DB::SqlConnection::Flag::UseLucene, + DPL::DB::SqlConnection::Flag::RW); + + connection.ExecCommand("CREATE TABLE testFloat(value FLOAT);"); + + DPL::DB::SqlConnection::DataCommandAutoPtr insertCommand = connection.PrepareDataCommand( + "INSERT INTO testFloat VALUES (?)"); + + DPL::DB::SqlConnection::DataCommandAutoPtr selectCommand = connection.PrepareDataCommand( + "SELECT value FROM testFloat"); + + insertCommand->BindFloat(1, 10.2545f); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + insertCommand->BindFloat(1, DPL::Optional(-90.6788f)); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + RUNNER_ASSERT(selectCommand->Step()); + float value = selectCommand->GetColumnFloat(0); + RUNNER_ASSERT(value > 10.2544 && value < 10.2546); + RUNNER_ASSERT(selectCommand->Step()); + value = *selectCommand->GetColumnOptionalFloat(0); + RUNNER_ASSERT(value > -90.6789 && value < -90.6787); + selectCommand->Reset(); + + connection.ExecCommand("DROP TABLE testFloat;"); +} + +/* +Name: SqlConnection_Double +Description: tests bind and getColumn functions for double +Expected: Functions returns correct values +*/ +RUNNER_TEST(SqlConnection_Double) +{ + DPL::DB::SqlConnection connection(PATH_DB, DPL::DB::SqlConnection::Flag::UseLucene, + DPL::DB::SqlConnection::Flag::RW); + + connection.ExecCommand("CREATE TABLE testDouble(value DOUBLE);"); + + DPL::DB::SqlConnection::DataCommandAutoPtr insertCommand = connection.PrepareDataCommand( + "INSERT INTO testDouble VALUES (?)"); + + DPL::DB::SqlConnection::DataCommandAutoPtr selectCommand = connection.PrepareDataCommand( + "SELECT value FROM testDouble"); + + insertCommand->BindDouble(1, 10.2545); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + insertCommand->BindDouble(1, DPL::Optional(-90.6788)); + RUNNER_ASSERT(!insertCommand->Step()); + insertCommand->Reset(); + + RUNNER_ASSERT(selectCommand->Step()); + double value = selectCommand->GetColumnDouble(0); + RUNNER_ASSERT(value > 10.2544 && value < 10.2546); + RUNNER_ASSERT(selectCommand->Step()); + value = *selectCommand->GetColumnOptionalDouble(0); + RUNNER_ASSERT(value > -90.6789 && value < -90.6787); + selectCommand->Reset(); + + connection.ExecCommand("DROP TABLE testDouble;"); +} diff --git a/tests/dbus/CMakeLists.txt b/tests/dbus/CMakeLists.txt new file mode 100644 index 0000000..4a1f338 --- /dev/null +++ b/tests/dbus/CMakeLists.txt @@ -0,0 +1,63 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) +# @version 1.0 +# @brief +# + +INCLUDE(FindPkgConfig) + +PKG_CHECK_MODULES(DEPENDENCIES gthread-2.0 REQUIRED) + +SET(TARGET_DBUS_TESTS "wrt-commons-tests-dbus") +SET(TARGET_DBUS_TEST_SERVICE "wrt-commons-tests-dbus-test-service") + +SET(DBUS_TESTS_SRCS + ${TESTS_DIR}/dbus/main.cpp + ${TESTS_DIR}/dbus/test_cases.cpp + ${TESTS_DIR}/dbus/dbus_test.cpp + ${TESTS_COMMON_DIR}/src/loop_control.cpp +) + +SET(DBUS_TEST_SERVICE_SRCS + ${TESTS_DIR}/dbus/test_service.cpp + ${TESTS_COMMON_DIR}/src/loop_control.cpp +) + +WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_DBUS_TESTS} ${TARGET_DPL_DBUS_EFL}) +WRT_TEST_INCLUDE_DIRECTORIES(${TARGET_DBUS_TESTS} + ${TESTS_COMMON_DIR}/include + ${DEPENDENCIES_INCLUDE_DIRS} +) +WRT_TEST_LINK_DIRECTORIES(${TARGET_DBUS_TESTS} ${DEPENDENCIES_LIBRARY_DIRS}) +WRT_TEST_TARGET_LINK_LIBRARIES(${TARGET_DBUS_TESTS} ${DEPENDENCIES_LIBRARIES}) +WRT_TEST_BUILD(${TARGET_DBUS_TESTS} ${DBUS_TESTS_SRCS}) +WRT_TEST_INSTALL(${TARGET_DBUS_TESTS}) + +WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_DBUS_TEST_SERVICE} ${TARGET_DPL_DBUS_EFL}) +WRT_TEST_INCLUDE_DIRECTORIES(${TARGET_DBUS_TEST_SERVICE} + ${TESTS_COMMON_DIR}/include + ${DEPENDENCIES_INCLUDE_DIRS} +) +WRT_TEST_LINK_DIRECTORIES(${TARGET_DBUS_TEST_SERVICE} ${DEPENDENCIES_LIBRARY_DIRS}) +WRT_TEST_TARGET_LINK_LIBRARIES(${TARGET_DBUS_TEST_SERVICE} ${DEPENDENCIES_LIBRARIES}) +WRT_TEST_BUILD(${TARGET_DBUS_TEST_SERVICE} ${DBUS_TEST_SERVICE_SRCS}) +WRT_TEST_INSTALL(${TARGET_DBUS_TEST_SERVICE}) + +INSTALL(FILES + ${TESTS_DIR}/dbus/data/org.tizen.DBusTestService.service + DESTINATION /usr/share/dbus-1/services +) diff --git a/tests/dbus/data/org.tizen.DBusTestService.service b/tests/dbus/data/org.tizen.DBusTestService.service new file mode 100644 index 0000000..94b3d67 --- /dev/null +++ b/tests/dbus/data/org.tizen.DBusTestService.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.tizen.DBusTestService +Exec=/usr/bin/wrt-commons-tests-dbus-test-service diff --git a/tests/dbus/dbus_test.cpp b/tests/dbus/dbus_test.cpp new file mode 100644 index 0000000..cabdf90 --- /dev/null +++ b/tests/dbus/dbus_test.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file dbus_test.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @brief Implementation file for DBusTest and DBusTestManager. + */ + +#include +#include "loop_control.h" +#include "dbus_test.h" + +DBusTest::DBusTest(const std::string& name) : + m_name(name), + m_status(Status::NONE) +{} + +void DBusTest::run(unsigned int timeout) +{ + DPL::Event::ControllerEventHandler::Touch(); + DPL::Event::ControllerEventHandler::Touch(); + + DPL::Event::ControllerEventHandler::PostTimedEvent( + TimeoutEvent(), timeout); + + LoopControl::wrt_start_loop(); + + switch (m_status) { + case Status::FAILED: + throw DPL::Test::TestRunner::TestFailed(m_name.c_str(), + __FILE__, + __LINE__, + m_message); + + case Status::SUCCESS: + case Status::NONE: + default: + break; + } +} + +void DBusTest::quit() +{ + DPL::Event::ControllerEventHandler::PostEvent(QuitEvent()); +} + +void DBusTest::setStatus(Status status) +{ + m_status = status; +} + +void DBusTest::setMessage(const std::string& message) +{ + m_message = message; +} + +void DBusTest::success() +{ + m_status = Status::SUCCESS; +} + +void DBusTest::fail(const std::string& message) +{ + m_status = Status::FAILED; + m_message = message; +} + +void DBusTest::OnEventReceived(const TimeoutEvent& /*event*/) +{ + fail("Test timed out."); + + // Saving one event dispatch since Quit and Timeout work on the same thread. + LoopControl::wrt_end_loop(); +} + +void DBusTest::OnEventReceived(const QuitEvent& /*event*/) +{ + LoopControl::wrt_end_loop(); +} + +DBusTestManager& DBusTestManager::getInstance() +{ + static DBusTestManager instance; + return instance; +} + +DBusTestManager::DBusTestManager() : m_test(NULL) { } + +DBusTest& DBusTestManager::getCurrentTest() const +{ + AssertMsg(NULL != m_test, "Test not set."); + + return *m_test; +} + +void DBusTestManager::setCurrentTest(DBusTest& test) +{ + m_test = &test; +} + +void DBusTestManager::clear() +{ + m_test = NULL; +} diff --git a/tests/dbus/dbus_test.h b/tests/dbus/dbus_test.h new file mode 100644 index 0000000..3c7ffe9 --- /dev/null +++ b/tests/dbus/dbus_test.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file dbus_test.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @brief Header file for DBusTest and DBusTestManager. + */ + +#ifndef WRT_TESTS_DBUS_TESTS_DBUS_TEST_H +#define WRT_TESTS_DBUS_TESTS_DBUS_TEST_H + +#include +#include +#include + +DECLARE_GENERIC_EVENT_0(QuitEvent) +DECLARE_GENERIC_EVENT_0(TimeoutEvent) + +class DBusTest : + private DPL::Event::Controller::Type> +{ + public: + enum class Status + { + NONE, + SUCCESS, + FAILED + }; + + explicit DBusTest(const std::string& name); + + void run(unsigned int timeout); + void quit(); + + void setStatus(Status status); + void setMessage(const std::string& message); + + void success(); + void fail(const std::string& message = std::string()); + + private: + void OnEventReceived(const TimeoutEvent& event); + void OnEventReceived(const QuitEvent& event); + + std::string m_name; + Status m_status; + std::string m_message; +}; + +class DBusTestManager : private DPL::Noncopyable +{ + public: + static DBusTestManager& getInstance(); + + DBusTest& getCurrentTest() const; + void setCurrentTest(DBusTest& test); + + void clear(); + + private: + DBusTestManager(); + + DBusTest* m_test; +}; + +#define DBUS_TEST(TestProc) \ + void DBus##TestProc(); \ + RUNNER_TEST(TestProc) \ + { \ + DBusTest test(#TestProc); \ + DBusTestManager::getInstance().setCurrentTest(test); \ + DBus##TestProc(); \ + DBusTestManager::getInstance().clear(); \ + } \ + void DBus##TestProc() + +#endif diff --git a/tests/dbus/main.cpp b/tests/dbus/main.cpp new file mode 100644 index 0000000..4dfd0b4 --- /dev/null +++ b/tests/dbus/main.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file main.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main. + */ + +#include "loop_control.h" +#include +#include + +int main(int argc, char *argv[]) +{ + LoopControl::init_loop(argc, argv); + + LogDebug("Running tests"); + int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, + argv); + + return status; +} diff --git a/tests/dbus/test_cases.cpp b/tests/dbus/test_cases.cpp new file mode 100644 index 0000000..15a7153 --- /dev/null +++ b/tests/dbus/test_cases.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file TestCases.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Implementation file for test cases for DBus internal tests. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "dbus_test.h" + +namespace { +const std::string dbusServiceName = "org.freedesktop.DBus"; +const std::string dbusObjectPath = "/"; +const std::string dbusInterfaceName = "org.freedesktop.DBus"; +const std::string dbusMethodGetId = "GetId"; + +const std::string serviceName = "org.tizen.DBusTestService"; +const std::string objectPath = "/org/tizen/DBusTestService"; +const std::string interfaceName = "org.tizen.DBusTestService"; +const std::string methodNameEcho = "echo"; +const std::string methodNameQuit = "quit"; +const std::string nodeInfo = + "" + "" + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +const std::string challenge = "Hello world!"; + +const int DEFAULT_TIMEOUT = 2; // in seconds +} + +RUNNER_TEST_GROUP_INIT(DPL) + +/* +Name: AcquireSessionBus +Description: tests acquiring session bus +Expected: no exceptions +*/ +RUNNER_TEST(AcquireSessionBus) +{ + try { + DPL::DBus::Connection::sessionBus(); + } catch (const DPL::DBus::Exception& ex) { + RUNNER_ASSERT_MSG(false, ex.DumpToString()); + } +} + +/* +Name: AcquireSystemBus +Description: tests acquiring system bus +Expected: no exceptions +*/ +RUNNER_TEST(AcquireSystemBus) +{ + try { + DPL::DBus::Connection::systemBus(); + } catch (const DPL::DBus::Exception& ex) { + RUNNER_ASSERT_MSG(false, ex.DumpToString()); + } +} + +/* +Name: ServerCreateFail +Description: tests creating server with wrong address +Expected: exception should occur +*/ +RUNNER_TEST(ServerCreateFail) +{ + bool exceptionCaught = false; + try { + DPL::DBus::ServerPtr server = DPL::DBus::Server::create("wrong address"); + } catch (const DPL::Exception& ex) { + exceptionCaught = true; + } + RUNNER_ASSERT(exceptionCaught); +} + +/* +Name: ServerCreateAndConnection +Description: tests creating server and connecting to it +Expected: no exceptions +*/ +RUNNER_TEST(ServerCreateAndConnection) +{ + try { + DPL::DBus::ServerPtr server = DPL::DBus::Server::create("unix:abstract=/tmp/testAddresss"); + server->start(); + DPL::DBus::ConnectionPtr con = DPL::DBus::Connection::connectTo("unix:abstract=/tmp/testAddresss"); + RUNNER_ASSERT(con); + } catch (const DPL::DBus::Exception& ex) { + RUNNER_ASSERT_MSG(false, ex.DumpToString()); + } +} + +/* +Name: ConnectionFail +Description: tests creating connection when server is not running +Expected: exception should occur +*/ +RUNNER_TEST(ConnectionFail) +{ + bool exceptionCaught = false; + try { + DPL::DBus::ConnectionPtr con = DPL::DBus::Connection::connectTo("unix:abstract=/tmp/testAddresss"); + RUNNER_ASSERT(con); + } catch (const DPL::DBus::Exception& ex) { + exceptionCaught = true; + } + RUNNER_ASSERT(exceptionCaught); +} + +/* +Name: ConnectionFail2 +Description: tests creating connection when server is running on different address +Expected: exception should occur +*/ +RUNNER_TEST(ConnectionFail2) +{ + bool exceptionCaught = false; + try { + DPL::DBus::ServerPtr server = DPL::DBus::Server::create("unix:abstract=/tmp/testAddresssToFail"); + server->start(); + DPL::DBus::ConnectionPtr con = DPL::DBus::Connection::connectTo("unix:abstract=wrongAddress"); + RUNNER_ASSERT(con); + } catch (const DPL::DBus::Exception& ex) { + exceptionCaught = true; + } + RUNNER_ASSERT(exceptionCaught); +} + + + +/* +Name: ParseNodeInfo +Description: creates dbus interface from xml string +Expected: interface should be created correctly +*/ +RUNNER_TEST(ParseNodeInfo) +{ + try { + auto ifaces = DPL::DBus::Interface::fromXMLString(nodeInfo); + RUNNER_ASSERT(!ifaces.empty()); + + auto iface = ifaces.at(0); + RUNNER_ASSERT(NULL != iface->getVTable()); + RUNNER_ASSERT(NULL != iface->getInfo()); + } catch (const DPL::DBus::Exception& ex) { + RUNNER_ASSERT_MSG(false, ex.DumpToString()); + } +} + +/* +Name: InvokeRemoteMethod +Description: performs procedure call via dbus +Expected: call should return not empty id +*/ +RUNNER_TEST(InvokeRemoteMethod) +{ + try { + auto connection = DPL::DBus::Connection::systemBus(); + auto freedesktop = connection->createObjectProxy(dbusServiceName, + dbusObjectPath); + auto getId = freedesktop->createMethodProxy + (dbusInterfaceName, dbusMethodGetId); + RUNNER_ASSERT(!getId().empty()); + } catch (const DPL::DBus::Exception& ex) { + RUNNER_ASSERT_MSG(false, ex.DumpToString()); + } +} + +class RegisterServiceListener : + public DPL::Event::EventListener +{ + public: + void OnEventReceived( + const DPL::DBus::ConnectionEvents::ServiceNameAcquiredEvent& event) + { + DBusTest& test = DBusTestManager::getInstance().getCurrentTest(); + + auto name = event.GetArg0(); + if (serviceName == name) { + test.success(); + } else { + test.fail("Acquired service name: " + name); + } + test.quit(); + } +}; + +/* +Name: RegisterService +Description: tests event listener for AcquiredEvent in context of dbus +Expected: event should be received +*/ +DBUS_TEST(RegisterService) +{ + try { + RegisterServiceListener listener; + + auto connection = DPL::DBus::Connection::sessionBus(); + connection->DPL::Event::EventSupport:: + AddListener(&listener); + connection->registerService(serviceName); + + DBusTestManager::getInstance().getCurrentTest().run(DEFAULT_TIMEOUT); + + connection->unregisterService(serviceName); + + } catch (const DPL::DBus::Exception& ex) { + RUNNER_ASSERT_MSG(false, ex.DumpToString()); + } +} + +/** + * This test checks: + * - object registration (done on the wrt-dbus-test-service side) + * - service registration (done on the wrt-dbus-test-service side) + * - dispatching method calls (done on the wrt-dbus-test-service side) + * - launching dbus service on demand + * - invoking remote method(s) + */ +DBUS_TEST(InvokeTestService) +{ + try { + auto connection = DPL::DBus::Connection::sessionBus(); + auto testService = connection->createObjectProxy(serviceName, + objectPath); + auto echo = testService->createMethodProxy + (interfaceName, methodNameEcho); + auto response = echo(challenge); + + testService->createMethodProxy(interfaceName, methodNameQuit) (); + + RUNNER_ASSERT_MSG(response == challenge, + "[challenge = " << challenge << + ", response = " << response << "]"); + } catch (const DPL::DBus::Exception& ex) { + RUNNER_ASSERT_MSG(false, ex.DumpToString()); + } +} diff --git a/tests/dbus/test_service.cpp b/tests/dbus/test_service.cpp new file mode 100644 index 0000000..510e4c5 --- /dev/null +++ b/tests/dbus/test_service.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test_service.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @brief Implementation file for wrt-dbus-test-service. + */ + +#include +#include +#include +#include +#include +#include + +namespace { +const std::string serviceName = "org.tizen.DBusTestService"; +const std::string objectPath = "/org/tizen/DBusTestService"; +const std::string interfaceName = "org.tizen.DBusTestService"; +const std::string methodNameEcho = "echo"; +const std::string methodNameQuit = "quit"; +const std::string nodeInfo = + "" + "" + " " + " " + " " + " " + " " + " " + " " + " " + ""; +} + +class TestServiceDispatcher : public DPL::DBus::Dispatcher +{ + private: + void onMethodCall(GDBusConnection* /*connection*/, + const gchar* /*sender*/, + const gchar* /*objectPath*/, + const gchar* /*interfaceName*/, + const gchar* methodName, + GVariant* parameters, + GDBusMethodInvocation* invocation) + { + if (methodNameEcho == methodName) { + LogDebug("Echo"); + g_dbus_method_invocation_return_value(invocation, + parameters); + } else if (methodNameQuit == methodName) { + LogDebug("Quit"); + g_dbus_method_invocation_return_value(invocation, NULL); + LoopControl::wrt_end_loop(); + } + } +}; + +int main(int argc, char* argv[]) +{ + LoopControl::init_loop(argc, argv); + TestServiceDispatcher dispatcher; + + auto iface = DPL::DBus::Interface::fromXMLString(nodeInfo).at(0); + iface->setDispatcher(&dispatcher); + auto object = DPL::DBus::Object::create(objectPath, iface); + auto connection = DPL::DBus::Connection::sessionBus(); + connection->registerObject(object); + connection->registerService(serviceName); + LoopControl::wrt_start_loop(); + + return 0; +} diff --git a/tests/event/CMakeLists.txt b/tests/event/CMakeLists.txt new file mode 100644 index 0000000..08fa4fa --- /dev/null +++ b/tests/event/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) +# @version 1.0 +# @brief +# + +# +# Test files +# +# Define all DPL tests sources. +# Runner is responsible for runnint it all and +# generating proper output files +# + +SET(TARGET_NAME "wrt-commons-tests-event") + +# Set DPL tests sources +SET(DPL_TESTS_EVENT_SOURCES + ${TESTS_DIR}/event/main.cpp + ${TESTS_DIR}/event/test_controller.cpp + ${TESTS_DIR}/event/test_event_support.cpp + ${TESTS_DIR}/event/test_ic_delegate.cpp + ${TESTS_DIR}/event/test_property.cpp +) + +WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_NAME} ${TARGET_DPL_EVENT_EFL}) +WRT_TEST_BUILD(${TARGET_NAME} ${DPL_TESTS_EVENT_SOURCES}) +WRT_TEST_INSTALL(${TARGET_NAME}) \ No newline at end of file diff --git a/tests/event/main.cpp b/tests/event/main.cpp new file mode 100644 index 0000000..4ed6191 --- /dev/null +++ b/tests/event/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file main.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main. + */ + +#include + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} diff --git a/tests/event/test_controller.cpp b/tests/event/test_controller.cpp new file mode 100644 index 0000000..5308720 --- /dev/null +++ b/tests/event/test_controller.cpp @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_controller.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test controller + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +namespace { + unsigned int seed = time(NULL); +} + +class IntController : + public DPL::Event::Controller::Type> +{ + private: + int m_value; + + protected: + virtual void OnEventReceived(const int &event) + { + m_value = event; + } + + public: + IntController() : + m_value(-1) + {} + + int Value() const + { + return m_value; + } +}; + +DECLARE_GENERIC_EVENT_1(DoneSignalEvent, DPL::WaitableEvent *) + +class ThreadController : + public DPL::Event::Controller::Type> +{ + private: + DPL::Thread *m_value; + + protected: + virtual void OnEventReceived(const DoneSignalEvent &event) + { + m_value = DPL::Thread::GetCurrentThread(); + event.GetArg0()->Signal(); + } + + public: + ThreadController() : + m_value(NULL) + {} + + DPL::Thread *Value() const + { + return m_value; + } +}; + +struct StrangeStruct +{ + int a; + float b; + double c; +}; + +class StrangeController : + public DPL::Event::Controller::Type> +{ + protected: + virtual void OnEventReceived(const char &event) + { + (void)event; + } + virtual void OnEventReceived(const short &event) + { + (void)event; + } + virtual void OnEventReceived(const int &event) + { + (void)event; + } + virtual void OnEventReceived(const long &event) + { + (void)event; + } + virtual void OnEventReceived(const unsigned char &event) + { + (void)event; + } + virtual void OnEventReceived(const unsigned short &event) + { + (void)event; + } + virtual void OnEventReceived(const unsigned int &event) + { + (void)event; + } + virtual void OnEventReceived(const unsigned long &event) + { + (void)event; + } + virtual void OnEventReceived(const float &event) + { + (void)event; + } + virtual void OnEventReceived(const double &event) + { + (void)event; + } + virtual void OnEventReceived(const StrangeStruct &event) + { + (void)event; + } +}; + +/* +Name: Controller_InitSimple +Description: tests initialization of simple int controller +Expected: no exceptions +*/ +RUNNER_TEST(Controller_InitSimple) +{ + IntController controller; + controller.Touch(); + RUNNER_ASSERT(controller.Value() == -1); +} + +/* +Name: Controller_InitStrange +Description: tests initialization of struct controller +Expected: no exceptions +*/ +RUNNER_TEST(Controller_InitStrange) +{ + StrangeController controller; + controller.Touch(); +} + +/* +Name: Controller_PostEventToThread +Description: tests post events to other thread +Expected: thread id gathered in event handling method should match id of created thread +*/ +RUNNER_TEST(Controller_PostEventToThread) +{ + ThreadController controller; + controller.Touch(); + + DPL::Thread thread; + thread.Run(); + + controller.SwitchToThread(&thread); + + DPL::WaitableEvent waitHandle; + + controller.PostEvent(DoneSignalEvent(&waitHandle)); + + DPL::WaitForSingleHandle(waitHandle.GetHandle()); + + controller.SwitchToThread(NULL); + + RUNNER_ASSERT(controller.Value() == &thread); +} + +/* +Name: Controller_PostTimedEventToThread +Description: tests post events to other thread with time delay +Expected: thread id gathered in event handling method should match id of created thread +*/ +RUNNER_TEST(Controller_PostTimedEventToThread) +{ + ThreadController controller; + controller.Touch(); + + DPL::Thread thread; + thread.Run(); + + controller.SwitchToThread(&thread); + + DPL::WaitableEvent waitHandle; + + controller.PostTimedEvent(DoneSignalEvent(&waitHandle), 0.5); + + DPL::WaitForSingleHandle(waitHandle.GetHandle()); + + controller.SwitchToThread(NULL); + + RUNNER_ASSERT(controller.Value() == &thread); +} + +DECLARE_GENERIC_EVENT_2(TouchInThread, DPL::WaitableEvent *, DPL::Thread * *) +DECLARE_GENERIC_EVENT_2(TouchedControllerSignal, + DPL::WaitableEvent *, + DPL::Thread * *) + +class TouchInThreadController : + public DPL::Event::Controller::Type>, + private DPL::Event::Controller:: + Type> +{ + public: + typedef DPL::Event::Controller::Type> + PublicController; + typedef DPL::Event::Controller:: + Type> PrivateController; + + virtual void OnEventReceived(const TouchInThread &event) + { + // Touch controller in thread + PrivateController::Touch(); + + // Post signal + PrivateController::PostEvent(TouchedControllerSignal(event.GetArg0(), + event.GetArg1())); + } + + virtual void OnEventReceived(const TouchedControllerSignal &event) + { + // Return touched thread + *event.GetArg1() = DPL::Thread::GetCurrentThread(); + + // Signal waitable event + event.GetArg0()->Signal(); + } +}; + +/* +Name: Controller_TouchInThread +Description: tests ability to touch (initizilize / set destination thread) in creatd thread + other than thread were controlelr object was created +Expected: thread id gathered in event handling method should match id of created thread +*/ +RUNNER_TEST(Controller_TouchInThread) +{ + TouchInThreadController controller; + controller.PublicController::Touch(); + + DPL::Thread thread; + thread.Run(); + + controller.PublicController::SwitchToThread(&thread); + + DPL::WaitableEvent waitHandle; + DPL::Thread *touchedThread = NULL; + + controller.PublicController::PostEvent(TouchInThread(&waitHandle, + &touchedThread)); + + DPL::WaitForSingleHandle(waitHandle.GetHandle()); + + controller.PublicController::SwitchToThread(NULL); + + RUNNER_ASSERT(touchedThread == &thread); +} + +/* +Name: Controller_SynchronizedEvent +Description: tests ability to post synchronized events to ther thread +Expected: correct value should be saved when event was handled +*/ +RUNNER_TEST(Controller_SynchronizedEvent) +{ + IntController controller; + controller.Touch(); + + DPL::Thread thread; + thread.Run(); + + controller.SwitchToThread(&thread); + controller.PostSyncEvent(12345); + controller.SwitchToThread(NULL); + + RUNNER_ASSERT(controller.Value() == 12345); +} + +const int ControllersNumber = 5; +const int MaxEventsPerController = 1; +const int MaxEvents = ControllersNumber * MaxEventsPerController; +const int ControllersPerThread = 1; + +class TestController; //Forward Declaration + +typedef std::shared_ptr ControllerPtr; +typedef std::shared_ptr ThreadPtr; +typedef std::vector ControllerList; +typedef std::list ThreadList; + +DECLARE_GENERIC_EVENT_0(QuitEvent) +class QuitController : + public DPL::Event::Controller::Type>, + public DPL::ApplicationExt +{ + public: + explicit QuitController() : DPL::ApplicationExt(1, NULL, "test-app") + { + Touch(); + } + + protected: + virtual void OnEventReceived(const QuitEvent &) + { + Quit(); + } +}; + +struct TestContext +{ + ControllerList controllers; + ThreadList threads; + QuitController quitter; + DPL::Atomic g_ReceivedCounter; + DPL::Atomic g_SentCounter; +}; +typedef std::unique_ptr TestContextPtr; +TestContextPtr testContextPtr; + +DECLARE_GENERIC_EVENT_0(StartSendEvent) +DECLARE_GENERIC_EVENT_0(RandomEvent) +class TestController : + public DPL::Event::Controller::Type> +{ + public: + explicit TestController() + { + Touch(); + } + + protected: + virtual void OnEventReceived(const RandomEvent &) + { + ++testContextPtr->g_ReceivedCounter; + if (testContextPtr->g_ReceivedCounter == MaxEvents) { + testContextPtr->quitter.DPL::Event::ControllerEventHandler< + QuitEvent>::PostEvent(QuitEvent()); + return; + } + } + virtual void OnEventReceived(const StartSendEvent &) + { + for (int i = 0; i < MaxEventsPerController; ++i) { + if (testContextPtr->g_SentCounter > MaxEvents) { + return; + } + ++testContextPtr->g_SentCounter; + int id = rand_r(&seed) % static_cast(testContextPtr->controllers.size()); + testContextPtr->controllers.at(id)->DPL::Event:: + ControllerEventHandler::PostEvent(RandomEvent()); + } + } +}; + +/* +Name: Controllers_MultipleEvents +Description: tests controller coooperation. + This runs many controllers in many threads. Each controller sends + to other randomly chosen controller events. +Expected: Test is supposed to be ended when all limits of sent event will be reach + -> all scheduled event will be sent and received. +*/ +RUNNER_TEST(Controllers_MultipleEvents) +{ + srand(time(NULL) ); + + testContextPtr.reset(new TestContext()); + testContextPtr->controllers.reserve(ControllersNumber); + + for (int i = 0; i < ControllersNumber; ++i) { + if (testContextPtr->controllers.size() % ControllersPerThread == 0) { + ThreadPtr thread = ThreadPtr(new DPL::Thread()); + testContextPtr->threads.push_back(thread); + thread->Run(); + } + + ControllerPtr controller = ControllerPtr(new TestController()); + testContextPtr->controllers.push_back(controller); + if (testContextPtr->controllers.size() % 2 == 0) { + //This controller is being switched to thread (otherwise it is + // touched to main thread) + ThreadPtr thread = testContextPtr->threads.back(); + controller->SwitchToThread(thread.get()); + } + controller->DPL::Event::ControllerEventHandler:: + PostEvent(StartSendEvent()); + } + testContextPtr->quitter.Exec(); + RUNNER_ASSERT( + testContextPtr->g_SentCounter == testContextPtr->g_ReceivedCounter); + testContextPtr.reset(); +} diff --git a/tests/event/test_event_support.cpp b/tests/event/test_event_support.cpp new file mode 100644 index 0000000..d221fb9 --- /dev/null +++ b/tests/event/test_event_support.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_event_support.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file contains test for event support + */ + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GENERIC_EVENT_0(TestEvent) + +class TestListener : public DPL::Event::EventListener +{ + public: + explicit TestListener() : m_dummyVar(0) { } + void OnEventReceived(const TestEvent &) + { + m_dummyVar = 1; + } + int GetDummyVar() const + { + return m_dummyVar; + } + void ZeroDummyVar() + { + m_dummyVar = 0; + } + + private: + int m_dummyVar; +}; + +class TestEventSupport : + public DPL::Event::EventSupport +{ + public: + void TestEmitEvent() + { + EmitEvent(TestEvent()); + } +}; + +DECLARE_GENERIC_EVENT_0(QuitEvent) + +class QuitController : + public DPL::Event::Controller::Type>, + public DPL::ApplicationExt +{ + public: + QuitController() : DPL::ApplicationExt(1, NULL, "test-app") + { + Touch(); + } + + protected: + virtual void OnEventReceived(const QuitEvent &) + { + Quit(); + } +}; + +/* +Name: EventSupport_DestroyBeforeProcessing +Description: tests if remoign listener is full successfull +Expected: dummy var should be affected by explicit call of ZeroDummyVar(), + but no by emitting event after removing listener +*/ +RUNNER_TEST(EventSupport_DestroyBeforeProcessing) +{ + QuitController quitter; + quitter.PostTimedEvent(QuitEvent(), 1.0); + + TestListener eventListener; + { + TestEventSupport eventSupport; + eventSupport.AddListener(&eventListener); + eventSupport.TestEmitEvent(); + eventSupport.RemoveListener(&eventListener); + } + eventListener.ZeroDummyVar(); + + quitter.Exec(); + RUNNER_ASSERT(eventListener.GetDummyVar() == 0); +} + +int g_delegateTest; + +void OnDelegateTest(const int &k); + +void OnDelegateTest(const int &k) +{ + LogDebug("Got delegate call"); + g_delegateTest = k; +} + +class DelegateTestSupport : + public DPL::Event::EventSupport +{ + public: + void Test() + { + EmitEvent(7); + } +}; + +/* +Name: EventSupport_BindDelegate +Description: tests if event support derived class successfully propagates + event to registered listener +Expected: value of event should be passed to listener +*/ +RUNNER_TEST(EventSupport_BindDelegate) +{ + g_delegateTest = 0; + + DelegateTestSupport support; + support.AddListener(&OnDelegateTest); + + QuitController quitter; + quitter.PostTimedEvent(QuitEvent(), 1.0); + + support.Test(); + + quitter.Exec(); + + support.RemoveListener(&OnDelegateTest); + + RUNNER_ASSERT(g_delegateTest == 7); +} diff --git a/tests/event/test_ic_delegate.cpp b/tests/event/test_ic_delegate.cpp new file mode 100644 index 0000000..460cfee --- /dev/null +++ b/tests/event/test_ic_delegate.cpp @@ -0,0 +1,602 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_ic_delegate.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of fast delegate tests. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +RUNNER_TEST_GROUP_INIT(DPL) + +const int IntVal = 123; +const std::string StringVal = "someString"; + +typedef DPL::Event::ICDelegate<> GetNothingDlpType; +typedef DPL::Event::ICDelegate GetIntDlgType; +typedef DPL::Event::ICDelegate GetIntAndStringDlgType; +DECLARE_GENERIC_EVENT_1(GetNothingEvent, GetNothingDlpType) +DECLARE_GENERIC_EVENT_1(GetIntEvent, GetIntDlgType) +DECLARE_GENERIC_EVENT_1(GetIntAndStringEvent, GetIntAndStringDlgType) + +class ICTestController : + public DPL::Event::Controller::Type> +{ + public: + ICTestController() { } + + protected: + virtual void OnEventReceived(const GetNothingEvent& event) + { + event.GetArg0() (); //calling intercontext delegate + } + virtual void OnEventReceived(const GetIntEvent& event) + { + event.GetArg0() (IntVal); //calling intercontext delegate + } + + virtual void OnEventReceived(const GetIntAndStringEvent& event) + { + event.GetArg0() (IntVal, StringVal); //calling intercontext delegate + } +}; + +struct TestResult +{ + TestResult() : + m_correctThread0(false), + m_correctThread1(false), + m_correctThread2(false), + m_int(-1), + m_int2(-1), + m_string("") + {} + + void TestEventsPassed() + { + RUNNER_ASSERT(m_correctThread0); + RUNNER_ASSERT(m_correctThread1); + RUNNER_ASSERT(m_int == IntVal); + RUNNER_ASSERT(m_correctThread2); + RUNNER_ASSERT(m_int2 == IntVal); + RUNNER_ASSERT(m_string == StringVal); + } + + void TestEventsDidNotPass() + { + RUNNER_ASSERT(!m_correctThread0); + RUNNER_ASSERT(!m_correctThread1); + RUNNER_ASSERT(m_int == -1); + RUNNER_ASSERT(!m_correctThread2); + RUNNER_ASSERT(m_int2 == -1); + RUNNER_ASSERT(m_string == ""); + } + + bool m_correctThread0; + bool m_correctThread1; + bool m_correctThread2; + int m_int; + int m_int2; + std::string m_string; +}; + +class TestContextFreeClass : + protected DPL::Thread, + public DPL::Event::ICDelegateSupport +{ + public: + TestContextFreeClass(ICTestController* controller, TestResult* result) : + Thread(), + m_testResult(result), + m_controller(controller) + { + LogDebug("Context thread id = " << this); + } + + void Run() + { + LogDebug("Running Context Free thread"); + Thread::Run(); + } + + void Quit() + { + LogDebug("Exiting Context Free thread"); + Thread::Quit(); + } + + void Wait() + { + LogDebug("Waiting for thread"); + DPL::WaitForSingleHandle(m_waitable.GetHandle()); + } + + protected: + void OnNothing() + { + LogDebug("Received nothing in thread = " << GetCurrentThread()); + m_testResult->m_correctThread0 = (GetCurrentThread() == this); + } + + void OnIntReceive(int val) + { + LogDebug("Received int in thread = " << GetCurrentThread()); + m_testResult->m_correctThread1 = (GetCurrentThread() == this); + m_testResult->m_int = val; + } + + void OnIntAndStringReceive(int val, std::string stringval) + { + LogDebug("Received int and string in thread = " << GetCurrentThread()); + m_testResult->m_correctThread2 = (GetCurrentThread() == this); + m_testResult->m_int2 = val; + m_testResult->m_string = stringval; + m_waitable.Signal(); + } + + virtual int ThreadEntry() + { + GetNothingEvent getNothingEvent( + makeICDelegate( + &TestContextFreeClass::OnNothing)); + m_controller->DPL::Event::ControllerEventHandler:: + PostEvent( + getNothingEvent); + + GetIntEvent getIntEvent( + makeICDelegate( + &TestContextFreeClass::OnIntReceive)); + m_controller->DPL::Event::ControllerEventHandler:: + PostEvent( + getIntEvent); + + GetIntAndStringEvent getIntAndStringEvent( + makeICDelegate( + &TestContextFreeClass::OnIntAndStringReceive)); + m_controller->DPL::Event::ControllerEventHandler + ::PostEvent( + getIntAndStringEvent); + + return Thread::ThreadEntry(); + } + + private: + TestResult* m_testResult; + DPL::WaitableEvent m_waitable; + ICTestController* m_controller; +}; + +/* +Name: ICDelegate_0 +Description: checks if delegetes are correctly called +Expected: delegates should be called from right context +*/ +RUNNER_TEST(ICDelegate_0) +{ + DPL::Thread thread; + thread.Run(); + LogDebug("Controller thread id = " << &thread); + + ICTestController testController; + testController.Touch(); + testController.SwitchToThread(&thread); + + TestResult result; + TestContextFreeClass* contextFree = + new TestContextFreeClass(&testController, &result); + result.TestEventsDidNotPass(); + + thread.Run(); + contextFree->Run(); + contextFree->Wait(); + contextFree->Quit(); + thread.Quit(); + + delete contextFree; + + result.TestEventsPassed(); +} + +/* +Name: ICDelegate_1 +Description: checks if delegetes are correctly called +Expected: delegates should be called from right context +*/ +RUNNER_TEST(ICDelegate_1) +{ + DPL::Thread thread; + LogDebug("Controller thread id = " << &thread); + + ICTestController testController; + testController.Touch(); + testController.SwitchToThread(&thread); + + TestResult result; + TestContextFreeClass* contextFree = + new TestContextFreeClass(&testController, &result); + result.TestEventsDidNotPass(); + + contextFree->Run(); + contextFree->Quit(); + delete contextFree; //deleting Delegates before actual Events are worked out + thread.Run(); + thread.Quit(); + + result.TestEventsDidNotPass(); +} + +class TestContextFree; +class TestRunnerInThread; + +namespace { +const int ControllersPerThread = 40; +const int ContextFreePerThread = 180; +const int TestsPerController = 110; +const int TestThreads = 23; +const int TestsPerThread = 100; +const int NumberOfEvents = 230; + +typedef std::shared_ptr ICTestControllerPtr; +typedef std::shared_ptr TestContextFreePtr; +typedef std::shared_ptr TestRunnerInThreadPtr; +typedef std::shared_ptr ThreadPtr; + +DPL::Mutex mutex; +std::list frees; +std::list ctrls; +std::list frees_threads; +std::list ctrls_threads; +} + +class TestContextFree : public DPL::Event::ICDelegateSupport +{ + public: + TestContextFree(ICTestController* controller, + int eventsCount) : + m_controller(controller), + m_eventsCount(eventsCount) + {} + + void Wait() + { + LogDebug("Waiting for thread"); + DPL::WaitForSingleHandle(m_waitable.GetHandle()); + } + + void OnNothing() + { + LogDebug("Got"); + m_eventsCount--; + if (m_eventsCount > 0) { + LogDebug("posting next event"); + GetIntAndStringEvent getIntAndStringEvent( + makeICDelegate( + &TestContextFree::OnIntAndStringReceive)); + LogDebug("posting next event ..."); + m_controller->DPL::Event::ControllerEventHandler< + GetIntAndStringEvent>::PostEvent( + getIntAndStringEvent); + LogDebug("posting next event done"); + } else { + LogDebug("test finished"); + m_waitable.Signal(); + } + } + + void OnIntReceive(int) + { + LogDebug("Got"); + m_eventsCount--; + if (m_eventsCount > 0) { + LogDebug("posting next event"); + GetNothingEvent getNothingEvent( + makeICDelegate( + &TestContextFree::OnNothing)); + LogDebug("posting next event ..."); + m_controller->DPL::Event::ControllerEventHandler:: + PostEvent( + getNothingEvent); + LogDebug("posting next event done"); + } else { + LogDebug("test finished"); + m_waitable.Signal(); + } + } + + void OnIntAndStringReceive(int, std::string) + { + LogDebug("Got"); + m_eventsCount--; + if (m_eventsCount > 0) { + LogDebug("posting next event"); + + GetIntEvent getIntEvent( + makeICDelegate( + &TestContextFree::OnIntReceive)); + LogDebug("posting next event ..."); + m_controller->DPL::Event::ControllerEventHandler:: + PostEvent( + getIntEvent); + LogDebug("posting next event done"); + } else { + LogDebug("test finished"); + m_waitable.Signal(); + } + } + + void StartTestOnNothing() + { + GetNothingEvent getNothingEvent( + makeICDelegate( + &TestContextFree::OnNothing)); + m_controller->DPL::Event::ControllerEventHandler:: + PostEvent( + getNothingEvent); + } + + void StartTestOnInt() + { + GetIntEvent getIntEvent( + makeICDelegate( + &TestContextFree::OnIntReceive)); + m_controller->DPL::Event::ControllerEventHandler:: + PostEvent( + getIntEvent); + } + + void StartTestOnIntAndString() + { + GetIntAndStringEvent getIntAndStringEvent( + makeICDelegate( + &TestContextFree::OnIntAndStringReceive)); + m_controller->DPL::Event::ControllerEventHandler + ::PostEvent( + getIntAndStringEvent); + } + + bool CheckTest() + { + LogDebug("Checking test result"); + return m_eventsCount == 0; + } + + private: + ICTestController* m_controller; + int m_eventsCount; + DPL::WaitableEvent m_waitable; +}; + +class TestRunnerInThread : public DPL::Thread +{ + public: + TestRunnerInThread(int events, int tests) : + m_eventsCount(events), + m_tests(tests) {} + + void WaitForInit() + { + LogDebug("Waiting for thread"); + DPL::WaitForSingleHandle(m_init.GetHandle()); + } + + protected: + virtual int ThreadEntry() + { + LogDebug("Thread starts"); + { + DPL::Mutex::ScopedLock lock(&mutex); + for (int i = 0; i < m_tests; ++i) { + if (i % TestsPerController == 0) { + if (ctrls.size() % ControllersPerThread == 0) { + ThreadPtr thread(new DPL::Thread()); + thread->Run(); + ctrls_threads.push_back(thread); + } + ICTestControllerPtr ptr(new ICTestController()); + ptr->Touch(); + ptr->SwitchToThread(ctrls_threads.back().get()); + ctrls.push_back(ptr); + + TestContextFreePtr t(new TestContextFree(ctrls.back().get(), + m_eventsCount)); + t->StartTestOnNothing(); + LogDebug(""); + frees.push_back(t); + } + } + } + m_init.Signal(); + LogDebug("Thread starts loop"); + return DPL::Thread::ThreadEntry(); + } + + private: + DPL::WaitableEvent m_init; + int m_eventsCount; + int m_tests; +}; + +/* +Name: ICDelegate_2 +Description: checks if delegetes are correctly called +Expected: delegates should be called from right context +*/ +RUNNER_TEST(ICDelegate_2) +{ + LogDebug("Creating test threads"); + for (int i = 0; i < TestThreads; ++i) { + TestRunnerInThreadPtr ptr( + new TestRunnerInThread(NumberOfEvents, TestsPerThread)); + frees_threads.push_back(ptr); + frees_threads.back()->Run(); + } + + FOREACH(it, frees_threads) { + (*it)->WaitForInit(); + } + LogDebug("Creating test threads done"); + + FOREACH(it, frees) { + LogDebug("..."); + (*it)->Wait(); + } + + FOREACH(it, frees) { + RUNNER_ASSERT((*it)->CheckTest()); + } + + frees.clear(); + + FOREACH(it, frees_threads) { + (*it)->Quit(); + } + + frees_threads.clear(); + + FOREACH(it, ctrls) { + (*it)->SwitchToThread(NULL); + } + + FOREACH(it, ctrls_threads) { + (*it)->Quit(); + } + + ctrls.clear(); + ctrls_threads.clear(); +} + +namespace ReuseCheck { +const int ReuseCount = 5; +typedef DPL::Event::ICDelegate<> GetNothingDlpType; +DECLARE_GENERIC_EVENT_1(ReuseCountEvent, GetNothingDlpType) + +class ICReuseTestController : + public DPL::Event::Controller::Type> +{ + public: + ICReuseTestController() + { + m_reuseCount = 0; + } + + protected: + virtual void OnEventReceived(const ReuseCountEvent& event) + { + event.GetArg0() (); //calling intercontext delegate + if (++m_reuseCount < ReuseCount) { + LogDebug("[Send] Reuse: " << m_reuseCount); + DPL::Event::ControllerEventHandler::PostEvent( + event); + } + } + + int m_reuseCount; +}; + +class ReuseTestContextFreeClass : + protected DPL::Thread, + public DPL::Event::ICDelegateSupport +{ + public: + ReuseTestContextFreeClass(ICReuseTestController* controller) : + Thread(), + m_controller(controller), + m_reuseCount(0) + { } + + void Run() + { + Thread::Run(); + } + void Quit() + { + Thread::Quit(); + } + void Wait() + { + DPL::WaitForSingleHandle(m_waitable.GetHandle()); + } + + protected: + void OnReuseReceive() + { + LogDebug("[Received] : " << ++m_reuseCount); + if (m_reuseCount == ReuseCount) { + m_waitable.Signal(); + } + } + + virtual int ThreadEntry() + { + ReuseCountEvent reuseEvent( + makeICDelegate( + &ReuseTestContextFreeClass::OnReuseReceive, + DPL::Event::ICD::Reuse::Yes)); + m_controller->DPL::Event::ControllerEventHandler:: + PostEvent( + reuseEvent); + + return Thread::ThreadEntry(); + } + + private: + DPL::WaitableEvent m_waitable; + ICReuseTestController* m_controller; + int m_reuseCount; +}; + +/* +Name: ICDelegate_3 +Description: checks if delegetes are correctly called +Expected: delegates should be called from right context +*/ +RUNNER_TEST(ICDelegate_3) +{ + DPL::Thread thread; + thread.Run(); + LogDebug("Controller thread id = " << &thread); + + ICReuseTestController testController; + testController.Touch(); + testController.SwitchToThread(&thread); + + ReuseTestContextFreeClass* contextFree = + new ReuseTestContextFreeClass(&testController); + + thread.Run(); + contextFree->Run(); + contextFree->Wait(); + contextFree->Quit(); + thread.Quit(); + + delete contextFree; + + RUNNER_ASSERT(true); +} +} //namespace ReuseCheck diff --git a/tests/event/test_property.cpp b/tests/event/test_property.cpp new file mode 100644 index 0000000..2760932 --- /dev/null +++ b/tests/event/test_property.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_property.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test property + */ +#include +#include +#include +#include + +namespace { +const int PROPERTY_VALUE_INT = 2; +const std::string PROPERTY_VALUE_STRING = "aaa"; +} + +int ReadSomething2(DPL::Event::Model */*model*/); +int ReadSomething2(DPL::Event::Model */*model*/) +{ + return PROPERTY_VALUE_INT; +} + +std::string ReadSomething(DPL::Event::Model */*model*/); +std::string ReadSomething(DPL::Event::Model */*model*/) +{ + return PROPERTY_VALUE_STRING; +} + +void WriteSomething(const std::string & /*value*/, DPL::Event::Model */*model*/); +void WriteSomething(const std::string & /*value*/, DPL::Event::Model */*model*/) +{} + +class MyModel : + public DPL::Event::Model +{ + public: + ~MyModel() {} + + DPL::Event::Property + Caption; + + DPL::Event::Property + Testproperty0; + + DPL::Event::Property + Testproperty1; + + DPL::Event::Property + Testproperty2; + + DPL::Event::Property Testproperty3; + + DPL::Event::Property Testproperty4; + + DPL::Event::Property + Testproperty5; + + MyModel() : + Caption(this, std::string("Foo caption")), + Testproperty0(this, std::string(""), &ReadSomething), + Testproperty1(this), + Testproperty2(this), + Testproperty3(this), + Testproperty4(this, std::string("test"), &ReadSomething, &WriteSomething), + Testproperty5(this, &ReadSomething2) + {} +}; + +std::string g_caption; + +void OnNameChanged(const DPL::Event::PropertyEvent &event); +void OnNameChanged(const DPL::Event::PropertyEvent &event) +{ + g_caption = event.value; +} + +/* +Name: Model_Test +Description: tests accessing and changing models properties +Expected: listener should get changed value +*/ +RUNNER_TEST(Model_Test) +{ + MyModel model; + + g_caption = "It is a bad caption"; + + model.Caption.AddListener(&OnNameChanged); + model.Caption.Set("Test name"); + + RUNNER_ASSERT(model.Testproperty4.Get() == PROPERTY_VALUE_STRING); + RUNNER_ASSERT(PROPERTY_VALUE_INT == model.Testproperty5.Get()); + RUNNER_ASSERT(g_caption == "Test name"); + RUNNER_ASSERT(model.Caption.Get() == "Test name"); + + model.Caption.RemoveListener(&OnNameChanged); +} diff --git a/tests/files_localization/CMakeLists.txt b/tests/files_localization/CMakeLists.txt new file mode 100644 index 0000000..3fdd256 --- /dev/null +++ b/tests/files_localization/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) +# @version 1.0 +# @brief +# + +# +# Test files +# +# Define all DPL tests sources. +# Runner is responsible for runnint it all and +# generating proper output files +# + +SET(TARGET_LOC "wrt-commons-tests-loc") + +SET(LOC_TESTS_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/test_localization.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_suite01.cpp +) + +WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_LOC} ${TARGET_WRT_DAO_RW_LIB} ${TARGET_CUSTOM_HANDLER_DAO_RW_LIB}) +WRT_TEST_BUILD(${TARGET_LOC} ${LOC_TESTS_SOURCES}) +WRT_TEST_INSTALL(${TARGET_LOC}) + +ADD_SUBDIRECTORY(files) + +INSTALL(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/wrt_db_localization_prepare.sh" + DESTINATION bin) diff --git a/tests/files_localization/files/CMakeLists.txt b/tests/files_localization/files/CMakeLists.txt new file mode 100644 index 0000000..be10866 --- /dev/null +++ b/tests/files_localization/files/CMakeLists.txt @@ -0,0 +1,31 @@ +INSTALL(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/one + DESTINATION + /opt/share/widget/tests/localization/widget1/res/wgt/locales/pl-en + ) + +INSTALL(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/one + ${CMAKE_CURRENT_SOURCE_DIR}/two.html + DESTINATION + /opt/share/widget/tests/localization/widget2/res/wgt/locales/pl-en + ) + +INSTALL(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/two.html + DESTINATION + /opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en + ) + +INSTALL(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/icon + DESTINATION + /opt/share/widget/tests/localization/widget1/res/wgt/locales/pl-en + ) + +INSTALL(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/icon2 + DESTINATION + /opt/share/widget/tests/localization/widget1/res/wgt/locales/pl-en + ) + diff --git a/tests/files_localization/files/icon b/tests/files_localization/files/icon new file mode 100644 index 0000000..e69de29 diff --git a/tests/files_localization/files/icon2 b/tests/files_localization/files/icon2 new file mode 100644 index 0000000..e69de29 diff --git a/tests/files_localization/files/one b/tests/files_localization/files/one new file mode 100644 index 0000000..e69de29 diff --git a/tests/files_localization/files/two.html b/tests/files_localization/files/two.html new file mode 100644 index 0000000..e69de29 diff --git a/tests/files_localization/test_localization.cpp b/tests/files_localization/test_localization.cpp new file mode 100644 index 0000000..ae4925a --- /dev/null +++ b/tests/files_localization/test_localization.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main + */ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + + int ret = system("/usr/bin/wrt_db_localization_prepare.sh start"); + if (ret != 0) { + LogError("Preparation script has return error: " << ret + << ". Quitting"); + return -1; + } + + WrtDB::WrtDatabase::attachToThreadRW(); + int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + WrtDB::WrtDatabase::detachFromThread(); + + ret = system("/usr/bin/wrt_db_localization_prepare.sh stop"); + if (ret != 0) { + LogError("Preparation script has return error: " << ret + << ". Quitting"); + return -1; + } + return status; +} + diff --git a/tests/files_localization/test_suite01.cpp b/tests/files_localization/test_suite01.cpp new file mode 100644 index 0000000..d163d1d --- /dev/null +++ b/tests/files_localization/test_suite01.cpp @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This file contains the declaration of widget dao class. + * + * @file test_suite01.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief + */ + +#include +#include +#include +#include +#include +#include + +namespace { + +STATIC_BLOCK +{ + WrtDB::LanguageTagList tags; + tags.push_back(L"pl-pl"); + tags.push_back(L"en-en"); + tags.push_back(L"pl-en"); + LanguageTagsProviderSingleton::Instance().setLanguageTags(tags); +} + +static const DPL::String widget1Path = + L"/opt/share/widget/tests/localization/widget1/"; +static const DPL::String widget2Path = + L"/opt/share/widget/tests/localization/widget2/"; + + +const std::string appId1("tizenid201"); +const std::string appId2("tizenid202"); + +} // anonymous namespace + +RUNNER_TEST(test01_getFilePathInWidgetPackageFromUrl){ + WrtDB::TizenAppId name = L"tizenid201"; //no difference if it is valid or invalid appId/pkgId, we fill database which has no intergrity constrainst + WrtDB::WidgetDAOReadOnly dao(name); + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"widget://one")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT( + *result == + L"/opt/share/widget/tests/localization/widget1/res/wgt/locales/pl-en/one"); +} + +RUNNER_TEST(test02_getFilePathInWidgetPackageFromUrl){ + WrtDB::TizenAppId name = L"tizenid202"; + WrtDB::WidgetDAOReadOnly dao(name); + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"widget://one")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT( + *result == + L"/opt/share/widget/tests/localization/widget2/res/wgt/locales/pl-en/one"); +} + +RUNNER_TEST(test03_getFilePathInWidgetPackageFromUrl){ + WrtDB::TizenAppId name = L"tizenid202"; + WrtDB::WidgetDAOReadOnly dao(name); + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"widget://two.html")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT( + *result == + L"/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html"); +} + +RUNNER_TEST(test04_getFilePathInWidgetPackageFromUrl) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"widget://two.html?a=1#b")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT( + *result == + L"/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html?a=1#b"); +} + +RUNNER_TEST(test05_getFilePathInWidgetPackageFromUrl) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"widget://two.html#a?b")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT( + *result == + L"/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html#a?b"); +} + +RUNNER_TEST(test06_getFilePathInWidgetPackageFromUrl) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"file://two.html")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT( + *result == + L"/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html"); +} + +RUNNER_TEST(test07_getFilePathInWidgetPackageFromUrl) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"file:///opt/share/widget/tests/localization/widget2/res/wgt/two.html")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT( + *result == + L"/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html"); +} + +RUNNER_TEST(test08_getFilePathInWidgetPackageFromUrl) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"file:///opt/share/widget/tests/localization/widget2/res/wgt/locales/pl-en/two.html")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT( + *result == + L"/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html"); +} + +RUNNER_TEST(test09_getFilePathInWidgetPackageFromUrl) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"app://two.html")); + + RUNNER_ASSERT(result.IsNull()); +} + +RUNNER_TEST(test10_getFilePathInWidgetPackageFromUrl) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"app://tizenid202/two.html")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT( + *result == + L"/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html"); +} + +RUNNER_TEST(test11_getFilePathInWidgetPackageFromUrl) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"dummy")); + + RUNNER_ASSERT(result.IsNull()); +} + +RUNNER_TEST(test12_getFilePathInWidgetPackageFromUrl) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl( + name, + DPL::String(L"app://tizenid202/notExisingFIle")); + + RUNNER_ASSERT(result.IsNull()); +} + +RUNNER_TEST(test13_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId1, "widget://one"); + + RUNNER_ASSERT_MSG(!result.empty(), "No result"); + RUNNER_ASSERT(result == "/opt/share/widget/tests/localization/widget1/res/wgt/locales/pl-en/one"); +} + +RUNNER_TEST(test14_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, "widget://one"); + + RUNNER_ASSERT_MSG(!result.empty(), "No result"); + RUNNER_ASSERT(result == "/opt/share/widget/tests/localization/widget2/res/wgt/locales/pl-en/one"); +} + +RUNNER_TEST(test15_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, "widget://two.html"); + + RUNNER_ASSERT_MSG(!result.empty(), "No result"); + RUNNER_ASSERT(result == "/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html"); +} + +RUNNER_TEST(test16_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, "widget://two.html?a=1#b"); + + RUNNER_ASSERT_MSG(!result.empty(), "No result"); + RUNNER_ASSERT(result == "/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html?a=1#b"); +} + +RUNNER_TEST(test17_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, "widget://two.html#a?b"); + + RUNNER_ASSERT_MSG(!result.empty(), "No result"); + RUNNER_ASSERT(result == "/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html#a?b"); +} + +RUNNER_TEST(test18_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, "file://two.html"); + + RUNNER_ASSERT_MSG(!result.empty(), "No result"); + RUNNER_ASSERT(result == "/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html"); +} + +RUNNER_TEST(test19_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, + "file:///opt/share/widget/tests/localization/widget2/res/wgt/two.html"); + + RUNNER_ASSERT_MSG(!result.empty(), "No result"); + RUNNER_ASSERT(result == "/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html"); +} + +RUNNER_TEST(test20_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, + "file:///opt/share/widget/tests/localization/widget2/res/wgt/locales/pl-en/two.html"); + + RUNNER_ASSERT_MSG(!result.empty(), "No result"); + RUNNER_ASSERT(result == "/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html"); +} + +RUNNER_TEST(test21_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, "app://two.html"); + + RUNNER_ASSERT(result.empty()); +} + +RUNNER_TEST(test22_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, "app://tizenid202/two.html"); + + RUNNER_ASSERT_MSG(!result.empty(), "No result"); + RUNNER_ASSERT(result == "/opt/share/widget/tests/localization/widget2/res/wgt/locales/en-en/two.html"); +} + +RUNNER_TEST(test23_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, "dummy"); + + RUNNER_ASSERT(result.empty()); +} + +RUNNER_TEST(test24_getFilePathInWidgetPackageFromUrl2) +{ + std::string result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(appId2, + "app://tizenid202/notExisingFIle"); + + RUNNER_ASSERT(result.empty()); +} + +RUNNER_TEST(test25_getFilePathInWidgetPackage) +{ + WrtDB::TizenAppId name = L"tizenid201"; + WrtDB::WidgetDAOReadOnly dao(name); + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackage( + name, + DPL::String(L"one")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT(*result == L"locales/pl-en/one"); +} + +RUNNER_TEST(test26_getFilePathInWidgetPackage) +{ + WrtDB::TizenAppId name = L"tizenid202"; + WrtDB::WidgetDAOReadOnly dao(name); + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackage( + name, + DPL::String(L"two.html")); + + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT(*result == L"locales/en-en/two.html"); +} + +RUNNER_TEST(test27_getFilePathInWidgetPackage) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + DPL::Optional result = W3CFileLocalization::getFilePathInWidgetPackage(name, L""); + RUNNER_ASSERT(result.IsNull()); + + result = W3CFileLocalization::getFilePathInWidgetPackage(name, L"/"); + RUNNER_ASSERT(result.IsNull()); + + result = W3CFileLocalization::getFilePathInWidgetPackage(name, L"//"); + RUNNER_ASSERT(result.IsNull()); + + result = W3CFileLocalization::getFilePathInWidgetPackage(name, L"dummy"); + RUNNER_ASSERT(result.IsNull()); + + result = W3CFileLocalization::getFilePathInWidgetPackage(name, L"/two.html/"); + RUNNER_ASSERT_MSG(!!result, "No result"); + RUNNER_ASSERT(*result == L"locales/en-en/two.html"); +} + +RUNNER_TEST(test28_getValidIconsList) +{ + WrtDB::TizenAppId name = L"not existing"; + + bool exceptionCaught = false; + + try { + W3CFileLocalization::WidgetIconList result = W3CFileLocalization::getValidIconsList(name); + } catch (WrtDB::WidgetDAOReadOnly::Exception::WidgetNotExist&) { + exceptionCaught = true; + } + RUNNER_ASSERT(exceptionCaught); +} + +RUNNER_TEST(test29_getValidIconsList) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + W3CFileLocalization::WidgetIconList result = W3CFileLocalization::getValidIconsList(name); + RUNNER_ASSERT(result.empty()); +} + + +RUNNER_TEST(test30_getValidIconsList) +{ + WrtDB::TizenAppId name = L"tizenid201"; + + W3CFileLocalization::WidgetIconList result = W3CFileLocalization::getValidIconsList(name); + RUNNER_ASSERT(result.size() == 2); + W3CFileLocalization::WidgetIconList::iterator iter = result.begin(); + RUNNER_ASSERT(iter->src == L"icon"); + RUNNER_ASSERT(iter->height == 250); + RUNNER_ASSERT(iter->width == 251); + iter++; + RUNNER_ASSERT(iter->src == L"icon2"); + RUNNER_ASSERT(iter->height == 252); + RUNNER_ASSERT(iter->width == 253); +} + +RUNNER_TEST(test31_getStartFileInfo) +{ + WrtDB::TizenAppId name = L"not existing"; + + bool exceptionCaught = false; + + try { + OptionalWidgetStartFileInfo result = W3CFileLocalization::getStartFileInfo(name); + } catch (WrtDB::WidgetDAOReadOnly::Exception::WidgetNotExist&) { + exceptionCaught = true; + } + RUNNER_ASSERT(exceptionCaught); +} + +RUNNER_TEST(test32_getStartFileInfo) +{ + WrtDB::TizenAppId name = L"tizenid202"; + + OptionalWidgetStartFileInfo result = W3CFileLocalization::getStartFileInfo(name); + RUNNER_ASSERT(result.IsNull()); +} + + +RUNNER_TEST(test33_getStartFileInfo) +{ + WrtDB::TizenAppId name = L"tizenid201"; + + OptionalWidgetStartFileInfo result = W3CFileLocalization::getStartFileInfo(name); + RUNNER_ASSERT(!result.IsNull()); + RUNNER_ASSERT(result->file == L"start_file"); + RUNNER_ASSERT(result->localizedPath == L"locales/en-en/start_file"); +} diff --git a/tests/files_localization/wrt_db_localization_prepare.sh b/tests/files_localization/wrt_db_localization_prepare.sh new file mode 100644 index 0000000..29c3806 --- /dev/null +++ b/tests/files_localization/wrt_db_localization_prepare.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -e + +trap 'echo "Script failed"; exit 1' ERR + +WRT_DB=/opt/dbspace/.wrt.db +WRT_DB_BCK=/tmp/wrt.db_backup +WIDGET_INSTALL_PATH=/opt/usr/apps + +case $1 in + start) + echo "start" + cp $WRT_DB $WRT_DB_BCK + wrt_commons_create_clean_db.sh + + #Widgets + INS_ALL_WIDGETEXT="insert into WidgetExtendedInfo(app_id, installed_path)" + INS_ALL_WIDGET="insert into WidgetInfo(app_id, tizen_appid)" + INS_ALL_ICON="insert into WidgetIcon(icon_id, app_id, icon_src, icon_width, icon_height)" + INS_ALL_LOCALIZED_START_FILE="insert into WidgetLocalizedStartFile(app_id, start_file_id, widget_locale, type, encoding)" + INS_ALL_START_FILE="insert into WidgetStartFile(start_file_id, app_id, src)" + + sqlite3 $WRT_DB "${INS_ALL_WIDGET} VALUES(1, 'tizenid201')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGET} VALUES(2, 'tizenid202')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGETEXT} VALUES(1, '/opt/share/widget/tests/localization/widget1')"; + sqlite3 $WRT_DB "${INS_ALL_WIDGETEXT} VALUES(2, '/opt/share/widget/tests/localization/widget2')"; + sqlite3 $WRT_DB "${INS_ALL_ICON} VALUES(1,1,'icon',251,250)"; + sqlite3 $WRT_DB "${INS_ALL_ICON} VALUES(2,1,'icon2',253,252)"; + sqlite3 $WRT_DB "${INS_ALL_LOCALIZED_START_FILE} VALUES(1,2,'en-en','test','test')"; + sqlite3 $WRT_DB "${INS_ALL_START_FILE} VALUES(2,1,'start_file')"; + exit 0 + ;; + stop) + echo "stop"; + cp $WRT_DB_BCK $WRT_DB + exit 0 + ;; + *) + echo "nothing to do" + exit 1 + ;; +esac diff --git a/tests/i18n/CMakeLists.txt b/tests/i18n/CMakeLists.txt new file mode 100644 index 0000000..9a90b43 --- /dev/null +++ b/tests/i18n/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) +# @version 1.0 +# @brief +# + +# +# Test files +# +# Define all DPL tests sources. +# Runner is responsible for runnint it all and +# generating proper output files +# + +SET(TARGET_NAME "wrt-commons-tests-i18n") + +# Set DPL tests sources +SET(DPL_TESTS_I18N_SOURCES + ${TESTS_DIR}/i18n/main.cpp + ${TESTS_DIR}/i18n/test_i18n_dao_read_only.cpp +) + +#include subdirectory +WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_NAME} ${TARGET_I18N_DAO_RO_LIB}) +WRT_TEST_BUILD(${TARGET_NAME} ${DPL_TESTS_I18N_SOURCES}) +WRT_TEST_INSTALL(${TARGET_NAME}) diff --git a/tests/i18n/main.cpp b/tests/i18n/main.cpp new file mode 100644 index 0000000..4ed6191 --- /dev/null +++ b/tests/i18n/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file main.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main. + */ + +#include + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} diff --git a/tests/i18n/test_i18n_dao_read_only.cpp b/tests/i18n/test_i18n_dao_read_only.cpp new file mode 100644 index 0000000..57dfe2d --- /dev/null +++ b/tests/i18n/test_i18n_dao_read_only.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_i18n_dao_read_only.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of i18n dao tests + */ +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(I18N) + +/* +Name: I18nDAOReadOnly_IsValidSubTag_True +Description: Test valid IANA subtag presence +Expected: Subtag found +*/ +RUNNER_TEST(I18nDAOReadOnly_IsValidSubTag_True) +{ + I18n::DB::Interface::attachDatabaseRO(); + bool result = I18n::DB::I18nDAOReadOnly::IsValidSubTag(L"aa", 0); + I18n::DB::Interface::detachDatabase(); + RUNNER_ASSERT_MSG(result, "Subtag not found"); +} + +/* +Name: I18nDAOReadOnly_IsValidSubTag_False +Description: Test invalid IANA subtag presence +Expected: Subtag not found +*/ +RUNNER_TEST(I18nDAOReadOnly_IsValidSubTag_False) +{ + I18n::DB::Interface::attachDatabaseRO(); + bool result = I18n::DB::I18nDAOReadOnly::IsValidSubTag(L"xxx000xxx", -1); + I18n::DB::Interface::detachDatabase(); + RUNNER_ASSERT_MSG(!result, "Subtag found"); +} diff --git a/tests/localizationTagsProvider/CMakeLists.txt b/tests/localizationTagsProvider/CMakeLists.txt new file mode 100644 index 0000000..fb3fee7 --- /dev/null +++ b/tests/localizationTagsProvider/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Marcin Kaminski (marcin.ka@samsung.com) +# @author Karol Pawlowski (k.pawlowski@samsung.com) +# @version 1.0 +# @brief +# + +SET(LOCALIZATION_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +PKG_CHECK_MODULES(TEST_PKGS + vconf + REQUIRED + ) + +WRT_INCLUDE_DIRECTORIES( + ${TEST_PKGS_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/modules/localization/include + ) + +WRT_LINK_DIRECTORIES(${TEST_PKGS_LIBRARY_DIRS}) +WRT_TARGET_LINK_LIBRARIES(${TEST_PKGS_LIBRARIES}) + +FILE(GLOB LOCALIZATION_TESTS_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*testcases.cpp") + +SET(TARGET_LOCALIZATION_TEST "wrt-commons-tests-localization") +WRT_TEST_BUILD(${TARGET_LOCALIZATION_TEST} ${LOCALIZATION_TESTS_SOURCES} tests_miscunit.cpp) +WRT_TEST_INSTALL(${TARGET_LOCALIZATION_TEST}) + diff --git a/tests/localizationTagsProvider/Localization_testcases.cpp b/tests/localizationTagsProvider/Localization_testcases.cpp new file mode 100644 index 0000000..295ca7c --- /dev/null +++ b/tests/localizationTagsProvider/Localization_testcases.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file Localization_testcases.cpp + * @author Marcin Kaminski (marcin.ka@samsung.com) + * @version 1.0 + * @brief This file contains tests for localization related code. + */ + +#include +#include +#include + +#include + +RUNNER_TEST_GROUP_INIT(LanguageTagsProvider) + +RUNNER_TEST(tagsFromSystemLocales) +{ + LogDebug("Generating tags from system locales"); + + char* currlocals = vconf_get_str(VCONFKEY_LANGSET); + LogDebug("Locales fetched from system settings: " << currlocals); + RUNNER_ASSERT_MSG(!!currlocals, "NULL locales received from system"); + int result = vconf_set_str(VCONFKEY_LANGSET, "en_US.UTF-8"); + LogDebug("Returned vconf set execution status: " << result); + RUNNER_ASSERT_MSG(result == 0, "Invalid value returned by vconf_set_str on setting locales"); + + /* Ensure that system locales where fetched */ + LanguageTagsProviderSingleton::Instance().resetLanguageTags(); + LogDebug("Language tags set based on current system locales"); + + LanguageTags ltlist = LanguageTagsProviderSingleton::Instance().getLanguageTags(); + RUNNER_ASSERT_MSG(!ltlist.empty(), "Empty tag list returned"); + + /* Correct list generated from given locales should contain: "en-US", "en" and "" */ + LanguageTags correct; + correct.push_back(L"en-US"); + correct.push_back(L"en"); + correct.push_back(L""); + + RUNNER_ASSERT_MSG( correct==ltlist, "Received and expected language tags lists differ"); + + /* Restore system locales */ + result = vconf_set_str(VCONFKEY_LANGSET, currlocals); + RUNNER_ASSERT_MSG(result == 0, "Invalid value returned by vconf_set_str on restoring locales"); + LogDebug("System locales restored"); +} + +RUNNER_TEST(tagsFromGivenLocales) +{ + LogDebug("Generating tags from given locales"); + + const char *locales1 = "it_IT.UTF-8", *locales2="en_GB"; + + LogDebug("Using locales with codepage: " << locales1); + LanguageTagsProviderSingleton::Instance().setLanguageTagsFromLocales(locales1); + LanguageTags ltlist = LanguageTagsProviderSingleton::Instance().getLanguageTags(); + /* Correct list generated from given locales should contain: "it-IT", "it" and + * two default values: "en" and "" */ + LanguageTags correct; + correct.push_back(L"it-IT"); + correct.push_back(L"it"); + correct.push_back(L""); + RUNNER_ASSERT_MSG(correct==ltlist, "Received and expected language tags lists differ"); + + LogDebug("Using locales without codepage: " << locales2); + LanguageTagsProviderSingleton::Instance().setLanguageTagsFromLocales(locales2); + ltlist = LanguageTagsProviderSingleton::Instance().getLanguageTags(); + correct.clear(); + correct.push_back(L"en-GB"); + correct.push_back(L"en"); + correct.push_back(L""); + RUNNER_ASSERT_MSG(correct==ltlist, "Received and expected language tags lists differ"); +} + +RUNNER_TEST(tagsFromNullLocales) +{ + LogDebug("Generating tags when NULL locales given"); + + LanguageTagsProviderSingleton::Instance().setLanguageTagsFromLocales(NULL); + LanguageTags ltlist = LanguageTagsProviderSingleton::Instance().getLanguageTags(); + /* List with two values "en" and "" should be returned */ + LanguageTags correct; + correct.push_back(L""); + RUNNER_ASSERT_MSG(correct==ltlist, "Received and expected language tags lists differ"); +} + + +RUNNER_TEST(tagsFromGivenTagList) +{ + LogDebug("Copying given tags list"); + + LogDebug("Correct full list (with default values)"); + LanguageTags correct; + correct.push_back(L"de-DE"); + correct.push_back(L"de"); + correct.push_back(L""); + LanguageTagsProviderSingleton::Instance().setLanguageTags(correct); + LanguageTags result = LanguageTagsProviderSingleton::Instance().getLanguageTags(); + RUNNER_ASSERT_MSG(correct==result, "Received and expected language tags lists differ"); + + LogDebug("Tags list without default values)"); + LanguageTags nondef; + nondef.push_back(L"de-DE"); + nondef.push_back(L"de"); + LanguageTagsProviderSingleton::Instance().setLanguageTags(correct); + result = LanguageTagsProviderSingleton::Instance().getLanguageTags(); + + /* Received list should contains elements from input list with default + * values added (as "correct" list has) */ + RUNNER_ASSERT_MSG(!result.empty(), "Empty tags list should never be returned"); + RUNNER_ASSERT_MSG(nondef!=result, "Received list is same as given incomplete one"); + RUNNER_ASSERT_MSG(correct==result, "Received and expected language tags lists differ"); +} + +RUNNER_TEST(tagsFromEmptyList) +{ + LogDebug("Generating tags when empty tag list given"); + + LanguageTags input; + LanguageTagsProviderSingleton::Instance().setLanguageTags(input); + LanguageTags result = LanguageTagsProviderSingleton::Instance().getLanguageTags(); + RUNNER_ASSERT_MSG(!result.empty(), "Empty tags list should never be returned"); +} + +RUNNER_TEST(defaultWidgetLocale) +{ + LogDebug("Adding default widget locales to language tags list"); + + LanguageTags input; + input.push_back(L"de-DE"); + input.push_back(L"de"); + input.push_back(L""); + LanguageTagsProviderSingleton::Instance().setLanguageTags(input); + LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(L"it"); + LanguageTags result = LanguageTagsProviderSingleton::Instance().getLanguageTags(); + RUNNER_ASSERT_MSG(result.size() == 4, "4 different language tags expected"); + LanguageTags reference; + reference.push_back(L"de-DE"); + reference.push_back(L"de"); + reference.push_back(L"it"); + reference.push_back(L""); + RUNNER_ASSERT_MSG(result == reference, "Received and expected language tags lists differ"); + LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(L"it"); + LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(L"de-DE"); + result = LanguageTagsProviderSingleton::Instance().getLanguageTags(); + RUNNER_ASSERT_MSG(result == reference, "Adding already included tag should not change tags list"); +} diff --git a/tests/localizationTagsProvider/README b/tests/localizationTagsProvider/README new file mode 100644 index 0000000..366e961 --- /dev/null +++ b/tests/localizationTagsProvider/README @@ -0,0 +1,13 @@ +Miscellaneous test suite +Unit tests (manifest files, wrt-api). Internal tests for new features in wrt. + +Binary file: wrt-tests-misc. Uses our test framework. Allows to use different +types of output. Text output shows results on console - green passed. +To run: +1. Install wrt-extra on target +2. Run wrt-tests-localization --output=text + +Automatic: YES +Included in Daily Build: NO +Included in Gerrit Builds: NO +Number of test cases: 75 \ No newline at end of file diff --git a/tests/localizationTagsProvider/tests_miscunit.cpp b/tests/localizationTagsProvider/tests_miscunit.cpp new file mode 100644 index 0000000..430cccf --- /dev/null +++ b/tests/localizationTagsProvider/tests_miscunit.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file tests_miscunit.cpp + * @author Marcin Kaminski (marcin.ka@samsung.com) + * @version 1.0 + * @brief This is main file for miscellaneous unit tests (tests of different + * classes, namespaces and functions). + */ + +#include +#include + +int main (int argc, char *argv[]) +{ + LogDebug("Starting miscellaneous unit tests"); + int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + + return status; +} diff --git a/tests/test/CMakeLists.txt b/tests/test/CMakeLists.txt new file mode 100644 index 0000000..ece6879 --- /dev/null +++ b/tests/test/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) +# @version 1.0 +# @brief +# + +SET(TARGET_NAME "wrt-commons-tests-test") + +# Set DPL tests sources +SET(DPL_TESTS_UTIL_SOURCES + ${TESTS_DIR}/test/main.cpp + ${TESTS_DIR}/test/runner_multiprocess.cpp + ${TESTS_DIR}/test/runner_child.cpp + ${TESTS_DIR}/test/test_process_pipe.cpp + ${TESTS_DIR}/test/test_abstract_input_reader.cpp + ${TESTS_DIR}/test/test_value_separated_reader.cpp +) + +#WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_NAME} ${TARGET_DPL_UTILS_EFL}) +WRT_TEST_BUILD(${TARGET_NAME} ${DPL_TESTS_UTIL_SOURCES}) +WRT_TEST_INSTALL(${TARGET_NAME}) diff --git a/tests/test/main.cpp b/tests/test/main.cpp new file mode 100644 index 0000000..42ffe3a --- /dev/null +++ b/tests/test/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main + */ +#include + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} + diff --git a/tests/test/runner_child.cpp b/tests/test/runner_child.cpp new file mode 100644 index 0000000..6dfc30d --- /dev/null +++ b/tests/test/runner_child.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file widget_version.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief Implementation file for test cases for engine internal tests + */ +#include +#include +#include +#include +#include +#include + + +namespace { +enum class TestResult +{ + PASS, + FAIL, + IGNORED, + TIMEOUT, + UNKNOWN +}; +} + +#define RUNNER_CHILD_TEST_EXPECT(name, result, message) \ + static void testExpectFunction##name(); \ + RUNNER_TEST(name) \ + { \ + TestResult eResult = result; \ + TestResult rResult = TestResult::UNKNOWN; \ + std::string eMessage = message; \ + Try \ + { \ + DPL::Test::RunChildProc(&testExpectFunction##name); \ + } \ + Catch(DPL::Test::TestRunner::TestFailed) \ + { \ + std::string rMessage = _rethrown_exception.GetMessage(); \ + size_t pos = rMessage.find(")"); \ + if(pos != std::string::npos && pos+2 <= rMessage.length()) \ + { \ + rMessage = rMessage.substr(pos+2); \ + } \ + if(rMessage == "Timeout") \ + { \ + rResult = TestResult::TIMEOUT; \ + } \ + else if(rMessage == "Ignored") \ + { \ + rResult = TestResult::IGNORED; \ + } \ + else if(rMessage == eMessage) \ + { \ + rResult = TestResult::FAIL; \ + } \ + else \ + { \ + RUNNER_ASSERT_MSG(false, "Fail message do not matches"); \ + } \ + } \ + if(rResult == TestResult::UNKNOWN) \ + { \ + rResult = TestResult::PASS; \ + } \ + RUNNER_ASSERT_MSG(eResult == rResult, "Expected other result"); \ + } \ + void testExpectFunction##name() \ + + +RUNNER_TEST_GROUP_INIT(DPL_TESTS_TEST_CHILD) + +RUNNER_CHILD_TEST_EXPECT(t00_pass, TestResult::PASS, "") +{ + RUNNER_ASSERT_MSG(1, "This test should pass"); +} + +RUNNER_CHILD_TEST_EXPECT(t01_pass, TestResult::PASS, "") +{ + RUNNER_ASSERT_MSG(1, "This test should pass"); +} + +RUNNER_CHILD_TEST_EXPECT(t02_fail, TestResult::FAIL, "This test should fail") +{ + RUNNER_ASSERT_MSG(0, "This test should fail"); +} + +RUNNER_CHILD_TEST_EXPECT(t03_fail_timeout, TestResult::TIMEOUT, "") +{ + sleep(20); + RUNNER_ASSERT_MSG(1, "This test should fail"); +} + +RUNNER_CHILD_TEST_EXPECT(t04_fail, TestResult::FAIL, "This test should fail") +{ + RUNNER_ASSERT_MSG(1, "This test should fail"); + RUNNER_ASSERT_MSG(1, "This test should fail"); + RUNNER_ASSERT_MSG(1, "This test should fail"); + RUNNER_ASSERT_MSG(1, "This test should fail"); + RUNNER_ASSERT_MSG(0, "This test should fail"); +} + +RUNNER_CHILD_TEST_EXPECT(t05_fail_child_died, TestResult::FAIL, "Reading pipe error") +{ + kill(getpid(), SIGKILL); + RUNNER_ASSERT_MSG(1, "This test should fail"); +} + +RUNNER_CHILD_TEST_EXPECT(t06_pass_8_second_test, TestResult::PASS, "") +{ + sleep(8); + RUNNER_ASSERT_MSG(1, "This test should pass"); +} + +RUNNER_CHILD_TEST_EXPECT(t07_fail_unknown_exception, TestResult::FAIL, "unhandled exeception") +{ + throw("hello"); +} + +RUNNER_CHILD_TEST_EXPECT(t08_fail_unknown_exception, TestResult::FAIL, "unhandled exeception") +{ + throw(1); +} + +RUNNER_CHILD_TEST_EXPECT(t09_fail_you_should_see_text_normal_assert, TestResult::FAIL, "Normal assert") +{ + RUNNER_ASSERT_MSG(0, "Normal assert"); +} + +RUNNER_CHILD_TEST_EXPECT(t10_pass, TestResult::PASS, "") +{ + RUNNER_ASSERT_MSG(1, "Normal assert"); +} + +RUNNER_CHILD_TEST_EXPECT(t11_ignore, TestResult::IGNORED, "Test ignored") +{ + RUNNER_IGNORED_MSG("Test ignored"); +} + + diff --git a/tests/test/runner_multiprocess.cpp b/tests/test/runner_multiprocess.cpp new file mode 100644 index 0000000..fcac88e --- /dev/null +++ b/tests/test/runner_multiprocess.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file runner_multiprocess.cpp + * @author Marcin Niesluchowski (m.niesluchow@samsung.com) + * @version 1.0 + * @brief Implementation file for test cases for engine internal tests + */ + +#include +#include +#include +#include + +namespace { +std::list split_string(std::string str, std::string delimiter) +{ + size_t pos = 0; + std::string token; + std::list stringList; + while ((pos = str.find(delimiter)) != std::string::npos) { + token = str.substr(0, pos); + stringList.push_back(token); + str.erase(0, pos + delimiter.length()); + } + if(str.length() != 0){ + stringList.push_back(token); + } + return stringList; +} +} + +#define RUNNER_MULTIPROCESS_TEST_EXPECT(name, messages) \ + static void testExpectFunction##name(); \ + RUNNER_TEST(name) \ + { \ + Try \ + { \ + DPL::Test::RunMultiProc(&testExpectFunction##name); \ + } \ + Catch(DPL::Test::TestRunner::TestFailed) \ + { \ + std::string eMsg = messages; \ + std::list eMessages = split_string(eMsg, "|"); \ + std::string rMessage = _rethrown_exception.GetMessage(); \ + if(eMsg.length() == 0 && rMessage.length() != 0) { \ + RUNNER_ASSERT_MSG(false, rMessage); \ + } \ + bool failedFound = false; \ + for(std::list::iterator it = eMessages.begin(); \ + it != eMessages.end(); \ + ++it) \ + { \ + if (!(*it).compare("TEST_FAILED")) { \ + failedFound = true; \ + continue; \ + } \ + RUNNER_ASSERT_MSG(rMessage.find(*it)!=std::string::npos, \ + "Key word " << *it << " not found in " << rMessage); \ + } \ + RUNNER_ASSERT_MSG( \ + rMessage.find("Reading pipe error")==std::string::npos, \ + "Reading pipe error"); \ + RUNNER_ASSERT_MSG( \ + rMessage.find("Timeout error")==std::string::npos, \ + "Timeout error"); \ + RUNNER_ASSERT_MSG(failedFound, "No TEST_FAILED found"); \ + } \ + Catch(DPL::Test::TestRunner::Ignored) \ + { \ + std::string eMsg = messages; \ + std::list eMessages = split_string(eMsg, "|"); \ + std::string rMessage = _rethrown_exception.GetMessage(); \ + if(eMsg.length() == 0 && rMessage.length() != 0) { \ + RUNNER_ASSERT_MSG(false, rMessage); \ + } \ + bool ignoredFound = false; \ + for(std::list::iterator it = eMessages.begin(); \ + it != eMessages.end(); \ + ++it) \ + { \ + if (!(*it).compare("TEST_IGNORED")) { \ + ignoredFound = true; \ + continue; \ + } \ + RUNNER_ASSERT_MSG(rMessage.find(*it)!=std::string::npos, \ + "Key word " << *it << " not found in " << rMessage); \ + } \ + RUNNER_ASSERT_MSG( \ + rMessage.find("Reading pipe error")==std::string::npos, \ + "Reading pipe error"); \ + RUNNER_ASSERT_MSG( \ + rMessage.find("Timeout error")==std::string::npos, \ + "Timeout error"); \ + RUNNER_ASSERT_MSG(ignoredFound, "No TEST_IGNORED found"); \ + } \ + } \ + void testExpectFunction##name() \ + +RUNNER_TEST_GROUP_INIT(DPL_TESTS_TEST_MULTIPROCESS) + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm00_pass, "") +{ + RUNNER_ASSERT_MSG(1, "This test should pass"); +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm01_pass, "") +{ + pid_t pid = fork(); + if(pid){ + sleep(2); + RUNNER_ASSERT_MSG(1, "This test should pass"); + } else { + RUNNER_ASSERT_MSG(1, "This test should pass"); + } + RUNNER_ASSERT_MSG(1, "This test should pass"); +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm02_pass, "") +{ + pid_t pid = fork(); + if(pid){ + RUNNER_ASSERT_MSG(1, "This test should pass"); + } else { + sleep(2); + RUNNER_ASSERT_MSG(1, "This test should pass"); + } + RUNNER_ASSERT_MSG(1, "This test should pass"); +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm03_pass, "") +{ + pid_t pid = fork(); + if(pid){ + pid = fork(); + if(pid){ + sleep(1); + } else { + sleep(2); + } + } else { + if(pid){ + sleep(2); + } else { + sleep(1); + } + } +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm04_fail, "TEST_FAILED|" + "This test should fail") +{ + RUNNER_ASSERT_MSG(0, "This test should fail"); +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm05_fail,"TEST_FAILED|" + "Test failed 1|" + "Test failed 2|" + "Test failed 3|" + "Test failed 4") +{ + pid_t pid = fork(); + if(pid){ + pid = fork(); + if(pid){ + RUNNER_ASSERT_MSG(0, "Test failed 1"); + } else { + RUNNER_ASSERT_MSG(0, "Test failed 2"); + } + } else { + pid = fork(); + if(pid){ + RUNNER_ASSERT_MSG(0, "Test failed 3"); + } else { + RUNNER_ASSERT_MSG(0, "Test failed 4"); + } + } +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm06_fail, "TEST_FAILED|" + "Test failed 1|" + "Test failed 2|" + "Test failed 3|" + "Test failed 4") +{ + pid_t pid = fork(); + if(pid){ + pid = fork(); + if(pid){ + sleep(2); + RUNNER_ASSERT_MSG(0, "Test failed 1"); + } else { + RUNNER_ASSERT_MSG(0, "Test failed 2"); + } + } else { + pid = fork(); + if(pid){ + RUNNER_ASSERT_MSG(0, "Test failed 3"); + } else { + RUNNER_ASSERT_MSG(0, "Test failed 4"); + } + } +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm07_fail, "TEST_FAILED|" + "Test failed 1|" + "Test failed 2|" + "Test failed 3|" + "Test failed 4") +{ + pid_t pid = fork(); + if(pid){ + pid = fork(); + if(pid){ + RUNNER_ASSERT_MSG(0, "Test failed 1"); + } else { + RUNNER_ASSERT_MSG(0, "Test failed 2"); + } + } else { + pid = fork(); + if(pid){ + sleep(2); + RUNNER_ASSERT_MSG(0, "Test failed 3"); + } else { + RUNNER_ASSERT_MSG(0, "Test failed 4"); + } + } +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm08_fail_unknown_exception, "TEST_FAILED|" + "unknown exception") +{ + throw("hello"); +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm09_fail_unknown_exception, "TEST_FAILED|" + "unknown exception") +{ + throw(1); +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm10_ignore, "TEST_IGNORED|" + "Test ignored") +{ + RUNNER_IGNORED_MSG("Test ignored"); +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm11_ignore, "TEST_IGNORED|" + "Test ignored 1|" + "Test ignored 2|" + "Test ignored 3|" + "Test ignored 4") +{ + pid_t pid = fork(); + if(pid){ + pid = fork(); + if(pid){ + RUNNER_IGNORED_MSG("Test ignored 1"); + } else { + RUNNER_IGNORED_MSG("Test ignored 2"); + } + } else { + pid = fork(); + if(pid){ + sleep(2); + RUNNER_IGNORED_MSG("Test ignored 3"); + } else { + RUNNER_IGNORED_MSG("Test ignored 4"); + } + } +} + +RUNNER_MULTIPROCESS_TEST_EXPECT(tm12_fail, "TEST_FAILED|" + "Test failed 1|" + "Test ignored 2|" + "Test ignored 3|" + "Test ignored 4") +{ + pid_t pid = fork(); + if(pid){ + pid = fork(); + if(pid){ + RUNNER_ASSERT_MSG(0, "Test failed 1"); + } else { + RUNNER_IGNORED_MSG("Test ignored 2"); + } + } else { + pid = fork(); + if(pid){ + sleep(2); + RUNNER_IGNORED_MSG("Test ignored 3"); + } else { + RUNNER_IGNORED_MSG("Test ignored 4"); + } + } +} diff --git a/tests/test/test_abstract_input_reader.cpp b/tests/test/test_abstract_input_reader.cpp new file mode 100644 index 0000000..8e74faa --- /dev/null +++ b/tests/test/test_abstract_input_reader.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_abstract_input_reader.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief tests for AbstractInputReader + */ + +#include +#include + +#include +#include +#include +#include +#include + +using namespace DPL; + +namespace { + +// TOKENIZER + +class DigitTokenizer : public AbstractInputTokenizer +{ +public: + DigitTokenizer() : m_valid(true) {} + + std::unique_ptr GetNextToken() + { + typedef AbstractInputTokenizer::Exception::TokenizerError TokenizerError; + + std::unique_ptr token; + + char buffer; + BinaryQueueAutoPtr baptr = m_input->Read(1); //not effective but it's test... + if(baptr.get() == NULL) + { + ThrowMsg(TokenizerError, "Input reading failed"); + } + if(baptr->Empty()) //end of source + { + return token; + } + baptr->FlattenConsume(&buffer,1); + if(!isdigit(buffer)) + { + ThrowMsg(TokenizerError, "Input source contains no digit characters/bytes"); + } + token.reset(new int(static_cast(buffer))); + return token; + } + + void Reset(std::shared_ptr ia) + { + AbstractInputTokenizer::Reset(ia); + m_valid = true; + } + + bool IsStateValid() + { + return true; + } + +private: + bool m_valid; +}; + +// PARSER + +class SumatorParser : public AbstractInputParser +{ +public: + SumatorParser() : m_sum(0) {} + + void ConsumeToken(std::unique_ptr && token) + { + m_sum += (*token - '0'); + } + + bool IsStateValid() + { + return true; + } + + int GetResult() const + { + return m_sum; + } + +private: + int m_sum; +}; + +// READER + +class Sumator : public AbstractInputReader +{ +public: + Sumator(std::shared_ptr ia) + : AbstractInputReader(ia, + std::unique_ptr(new SumatorParser()), + std::unique_ptr(new DigitTokenizer())) + {} +}; + +} + +RUNNER_TEST_GROUP_INIT(AbstractInputReader) + +RUNNER_TEST(AbstractInputReader_ByteSumatorInstance_Sum) +{ + const std::string data("1234567890"); + std::shared_ptr mem(new BinaryQueue()); + dynamic_cast(mem.get())->AppendCopy(data.c_str(), data.size()); + Sumator sum(mem); + int result = sum.ReadInput(); + RUNNER_ASSERT_MSG(result == 45, "Sum is invalid"); +} + +RUNNER_TEST(AbstractInputReader_ByteSumatorInstance_Exception) +{ + const std::string data("12345string90"); + std::shared_ptr mem(new BinaryQueue()); + dynamic_cast(mem.get())->AppendCopy(data.c_str(), data.size()); + Sumator sum(mem); + Try + { + sum.ReadInput(); + } + Catch(Sumator::Exception::TokenizerError) + { + return; + } + RUNNER_ASSERT_MSG(false, "Tokenizer exception should be thrown"); +} diff --git a/tests/test/test_process_pipe.cpp b/tests/test/test_process_pipe.cpp new file mode 100644 index 0000000..46405f9 --- /dev/null +++ b/tests/test/test_process_pipe.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_process_pipe.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of ProcessPipe tests + */ + +#include +#include +#include +#include + +#include + +using namespace DPL; + +RUNNER_TEST_GROUP_INIT(DPL) + +namespace { +void readAll(ProcessPipe & npp, BinaryQueue & result) +{ + do + { + BinaryQueueAutoPtr dataptr = npp.Read(4096); + + RUNNER_ASSERT_MSG(dataptr.get() != NULL, "Cannot read from pipe subprocess"); + + LogDebug("Size: " << dataptr->Size()); + + if(dataptr->Empty()) break; + result.AppendMoveFrom(*dataptr); + } + while(true); +} +} + +RUNNER_TEST(ProcessPipe_echo) +{ + ProcessPipe npp; + npp.Open("echo -e \"Test echo text\\nAnd new line\""); + BinaryQueue result; + readAll(npp, result); + npp.Close(); + + char buffer[100] = ""; + result.FlattenConsume(buffer, std::min(result.Size(), sizeof(buffer))); + + RUNNER_ASSERT_MSG(strcmp(buffer, "Test echo text\nAnd new line\n") == 0, "Echoed text in not equal"); +} + +RUNNER_TEST(ProcessPipe_double_open) +{ + ProcessPipe npp; + npp.Open("echo \"Test \""); + Try + { + npp.Open("echo \"Test\""); + } + Catch(DPL::ProcessPipe::Exception::DoubleOpen) + { + npp.Close(); + return; + } + npp.Close(); + RUNNER_ASSERT_MSG(false, "DoubleOpen not thrown"); +} + +RUNNER_TEST(ProcessPipe_double_close) +{ + ProcessPipe npp; + npp.Open("echo \"Test invalid\""); + npp.Close(); + Try + { + npp.Close(); + } + Catch(DPL::Exception) + { + RUNNER_ASSERT_MSG(false, "Second Close throws exception"); + } +} + +RUNNER_TEST(ProcessPipe_pipeerror_off) +{ + ProcessPipe npp(ProcessPipe::PipeErrorPolicy::OFF); + npp.Open("ls /nonexistingdirectory"); + BinaryQueue result; + readAll(npp, result); //TODO: fix this test + npp.Close(); +} + +RUNNER_TEST(ProcessPipe_pipeerror_pipe) +{ + //ls output dependent... + ProcessPipe npp(ProcessPipe::PipeErrorPolicy::PIPE); + npp.Open("ls /nonexistingdirectory"); + BinaryQueue result; + readAll(npp, result); + npp.Close(); + char buffer[100] = ""; + result.FlattenConsume(buffer, std::min(result.Size(), sizeof(buffer))); + + RUNNER_ASSERT_MSG(strcmp(buffer, "ls: cannot access /nonexistingdirectory: No such file or directory\n") == 0, "Ls error text in not equal"); +} diff --git a/tests/test/test_value_separated_reader.cpp b/tests/test/test_value_separated_reader.cpp new file mode 100644 index 0000000..af17c2a --- /dev/null +++ b/tests/test/test_value_separated_reader.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_value_separated_reader.cpp + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @brief tests for VSReader + */ + +#include +#include +#include + +#include + +using namespace DPL; + +RUNNER_TEST_GROUP_INIT(ValueSeparatedReader) + +RUNNER_TEST(ValueSeparatedReader_readValidCSV) +{ + std::string data; + data += "1-1,1-2,1-3,1-4\n"; + data += "2-1,2-2,2-3,2-4\n"; + data += "3-1,3-2,3-3,3-4\n"; + data += "4-1,4-2,4-3,4-4\n"; + std::shared_ptr mem(new BinaryQueue()); + dynamic_cast(mem.get())->AppendCopy(data.data(), data.size()); + CSVReader csv(mem); + VSResultPtr result = csv.ReadInput(); + RUNNER_ASSERT_MSG((*result)[0][0] == "1-1", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[0][1] == "1-2", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[0][2] == "1-3", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[0][3] == "1-4", "Wrong value"); + + RUNNER_ASSERT_MSG((*result)[1][0] == "2-1", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[1][1] == "2-2", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[1][2] == "2-3", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[1][3] == "2-4", "Wrong value"); + + RUNNER_ASSERT_MSG((*result)[2][0] == "3-1", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[2][1] == "3-2", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[2][2] == "3-3", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[2][3] == "3-4", "Wrong value"); + + RUNNER_ASSERT_MSG((*result)[3][0] == "4-1", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[3][1] == "4-2", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[3][2] == "4-3", "Wrong value"); + RUNNER_ASSERT_MSG((*result)[3][3] == "4-4", "Wrong value"); +} + +RUNNER_TEST(ValueSeparatedReader_readInvalidCSV) +{ + Try + { + std::string data; + data += "1-1,1-2,1-3,1-4\n"; + data += "2-1,2-2,2-3,2-4\n"; + data += "3-1,3-2,3-3\n"; + data += "4-1,4-2,4-3,4-4\n"; + std::shared_ptr mem(new BinaryQueue()); + dynamic_cast(mem.get())->AppendCopy(data.data(), data.size()); + CSVReader csv(mem); + VSResultPtr result = csv.ReadInput(); + } + Catch(CSVReader::Exception::ParserError) + { + return; + } + RUNNER_ASSERT_MSG(false, "Should throw parser error"); +} diff --git a/tests/unused/test_caller.cpp b/tests/unused/test_caller.cpp new file mode 100644 index 0000000..6f1a1ff --- /dev/null +++ b/tests/unused/test_caller.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_address.cpp + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of caller tests + */ + +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +// test stream class +class BinaryStream : public DPL::IStream +{ + public: + virtual void Read(size_t num, void * bytes) + { + for (unsigned i = 0; i < num; ++i) { + ((unsigned char*)bytes)[i] = data[i + readPosition]; + } + readPosition += num; + } + virtual void Write(size_t num, const void * bytes) + { + for (unsigned i = 0; i < num; ++i) { + data.push_back(((unsigned char*)bytes)[i]); + } + } + BinaryStream() + { + readPosition = 0; + } + virtual ~BinaryStream(){} + + private: + std::vector data; + unsigned readPosition; +}; + +static int return_func(int a, bool b) +{ + if (b) { + return a; + } else { + return 0; + } +} + +static int called = 0; + +static void void_func(int a) +{ + called = a; +} + +static struct VoidDelegate +{ + void operator()(int a) + { + called = a; + } +} voidDelegate; + +static struct ReturnDelegate +{ + int operator()(int a) + { + return a; + } +} returnDelegate; + +RUNNER_TEST(Caller_function_void) +{ + int a = 23; + BinaryStream stream; + DPL::Serialization::Serialize(stream, a); + called = 0; + DPL::Caller::Call(stream, void_func); + RUNNER_ASSERT(called == a); +} + +RUNNER_TEST(Caller_function_return) +{ + int a = 23; + bool b = true; + BinaryStream stream; + DPL::Serialization::Serialize(stream, a); + DPL::Serialization::Serialize(stream, b); + int result = DPL::Caller::Call(stream, return_func); + RUNNER_ASSERT(result == a); +} + +RUNNER_TEST(Caller_delegate_void) +{ + int a = 23; + BinaryStream stream; + called = 0; + DPL::Serialization::Serialize(stream, a); + DPL::Caller::CallDelegate(stream, voidDelegate); + RUNNER_ASSERT(called == a); +} + +RUNNER_TEST(Caller_delegate_return) +{ + int a = 23; + BinaryStream stream; + called = 0; + DPL::Serialization::Serialize(stream, a); + int result = 0; + DPL::Caller::CallDelegate(stream, returnDelegate, result); + RUNNER_ASSERT(result == a); +} diff --git a/tests/unused/test_crypto_hash.cpp b/tests/unused/test_crypto_hash.cpp new file mode 100644 index 0000000..dd208b6 --- /dev/null +++ b/tests/unused/test_crypto_hash.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_crypto_hash.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of test crypto hash + */ +#include +#include +RUNNER_TEST_GROUP_INIT(DPL) + +#define TEST_CRYPTO_HASH(Class, Input, Output) \ + Class crypto; \ + crypto.Append(Input); \ + crypto.Finish(); \ + RUNNER_ASSERT(crypto.ToString() == Output); + +RUNNER_TEST(CryptoHash_MD2) +{ + TEST_CRYPTO_HASH(DPL::Crypto::Hash::MD2, + "sample_input_string", + "c9f26439c9882cccc98467dbdf07b1fc"); +} + +RUNNER_TEST(CryptoHash_MD4) +{ + TEST_CRYPTO_HASH(DPL::Crypto::Hash::MD4, + "sample_input_string", + "8cd0720f7ec98c8e5f008afb54054677"); +} + +RUNNER_TEST(CryptoHash_MD5) +{ + TEST_CRYPTO_HASH(DPL::Crypto::Hash::MD5, + "sample_input_string", + "eb7ae4f28fecbd1fd777d9b7495fc8ec"); +} + +RUNNER_TEST(CryptoHash_SHA) +{ + TEST_CRYPTO_HASH(DPL::Crypto::Hash::SHA, + "sample_input_string", + "0a5725f3586616a4049730f3ba14c8aeda79ab21"); +} + +RUNNER_TEST(CryptoHash_SHA1) +{ + TEST_CRYPTO_HASH(DPL::Crypto::Hash::SHA1, + "sample_input_string", + "be0ed9040af0c2b772b2dd0776f6966b5f4d1206"); +} + +RUNNER_TEST(CryptoHash_DSS) +{ + TEST_CRYPTO_HASH(DPL::Crypto::Hash::DSS, + "sample_input_string", + "be0ed9040af0c2b772b2dd0776f6966b5f4d1206"); +} + +RUNNER_TEST(CryptoHash_DSS1) +{ + TEST_CRYPTO_HASH(DPL::Crypto::Hash::DSS1, + "sample_input_string", + "be0ed9040af0c2b772b2dd0776f6966b5f4d1206"); +} + +RUNNER_TEST(CryptoHash_ECDSA) +{ + TEST_CRYPTO_HASH(DPL::Crypto::Hash::ECDSA, + "sample_input_string", + "be0ed9040af0c2b772b2dd0776f6966b5f4d1206"); +} + +RUNNER_TEST(CryptoHash_SHA224) +{ + TEST_CRYPTO_HASH(DPL::Crypto::Hash::SHA224, + "sample_input_string", + "d4dde2370eb869f6e790133b94d58e45417392b9d899af883a274011"); +} + +RUNNER_TEST(CryptoHash_SHA256) +{ + TEST_CRYPTO_HASH( + DPL::Crypto::Hash::SHA256, + "sample_input_string", + "a470ec7c783ac51f9eb1772132e6bde1a053bbc81650719dd0ac62ecd93caf12"); +} + +RUNNER_TEST(CryptoHash_SHA384) +{ + TEST_CRYPTO_HASH( + DPL::Crypto::Hash::SHA384, + "sample_input_string", + "63d8bfa95c95c6906d1816965431c065278a655c60f786c9b246c1f73ba7ac557007f5064ba54ebd3a1988e6f37baa97"); +} + +RUNNER_TEST(CryptoHash_SHA512) +{ + TEST_CRYPTO_HASH( + DPL::Crypto::Hash::SHA512, + "sample_input_string", + "799317a140741937d9e5d8dbf9d3045d2c220de5ac33b3d5897acf873291ed14379eb15ef406d2284313d40edb0e01affac8efeb01cb47c2042e3e62a4a83d7d"); +} diff --git a/tests/unused/test_message_queue.cpp b/tests/unused/test_message_queue.cpp new file mode 100644 index 0000000..09990b7 --- /dev/null +++ b/tests/unused/test_message_queue.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_message_queue.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of message queue tests + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GENERIC_EVENT_0(QuitEvent) + +class QuitController : + public DPL::Controller::Type>, + public DPL::ApplicationExt +{ + public: + QuitController() : DPL::ApplicationExt(1, NULL, "test-app") + { + Touch(); + } + + protected: + virtual void OnEventReceived(const QuitEvent &) + { + Quit(); + } +}; + +RUNNER_TEST_GROUP_INIT(DPL) + +class CopyThread : + public DPL::Thread +{ + private: + bool m_success; + DPL::AbstractWaitableInput *m_input; + DPL::AbstractWaitableOutput *m_output; + std::size_t m_dataSize; + + public: + CopyThread(DPL::AbstractWaitableInput *input, + DPL::AbstractWaitableOutput *output, + std::size_t dataSize) : + m_success(true), + m_input(input), + m_output(output), + m_dataSize(dataSize) + { + LogDebug("Thread created"); + } + + protected: + virtual int ThreadEntry() + { + LogDebug("Entering copy thread"); + + Try + { + DPL::Copy(m_input, m_output, m_dataSize); + } + Catch(DPL::CopyFailed) + { + m_success = false; + + LogWarning("Copy failed!"); + return 0; + } + + LogDebug("Copy finished"); + return 0; + } +}; + +inline std::string BinaryQueueToString(const DPL::BinaryQueue &queue) +{ + char *buffer = new char[queue.Size()]; + queue.Flatten(buffer, queue.Size()); + std::string result = std::string(buffer, buffer + queue.Size()); + delete[] buffer; + return result; +} + +RUNNER_TEST(MessageQueue_DoubleCopy) +{ + DPL::BinaryQueue dataA; + DPL::MessageQueue dataB("/test_mqueue_dataB", true, false, 0660, true); + DPL::MessageQueue dataC("/test_mqueue_dataC", true, false, 0660, true); + DPL::BinaryQueue dataD; + + DPL::AbstractWaitableInputAdapter dataAdapterA(&dataA); + DPL::AbstractWaitableOutputAdapter dataAdapterD(&dataD); + + const std::string testData = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + "Cras elementum venenatis velit, sit amet vehicula odio gravida a." + "Curabitur id nibh id ante adipiscing sollicitudin." + "Maecenas in tellus vel augue vehicula pharetra hendrerit cursus est." + "" + "Ut malesuada quam porttitor dui euismod lacinia." + "Phasellus quis lectus sed lectus dictum tincidunt et vitae leo." + "Fusce id est massa, condimentum bibendum urna." + "Donec venenatis quam eget sapien vulputate egestas." + "Maecenas scelerisque lorem a neque molestie a varius erat condimentum." + "Maecenas varius hendrerit ligula, sed iaculis justo pretium id." + "Nunc sit amet nisl vitae justo tristique suscipit id eget tortor." + "" + "Pellentesque sollicitudin nulla at metus dapibus tincidunt." + "Integer consequat justo eget dui imperdiet iaculis." + "Sed vestibulum ipsum vitae libero accumsan non molestie metus adipiscing." + "" + "Vivamus quis dui enim, in blandit urna." + "In imperdiet lacus at orci elementum a scelerisque dui blandit." + "Donec vulputate enim metus, eget convallis ante." + "Etiam mollis enim eget eros pulvinar nec sagittis justo fermentum." + "" + "Vestibulum sed nunc eu leo lobortis ultrices." + "Nullam placerat nulla et est blandit nec interdum nunc pulvinar." + "Vivamus a lectus eget dui fermentum hendrerit."; + + QuitController quitter; + quitter.PostTimedEvent(QuitEvent(), 1.0); + + CopyThread threadA(&dataAdapterA, &dataB, testData.size()); + CopyThread threadB(&dataB, &dataC, testData.size()); + CopyThread threadC(&dataC, &dataAdapterD, testData.size()); + + dataA.AppendCopy(testData.c_str(), testData.size()); + + threadA.Run(); + threadB.Run(); + threadC.Run(); + + quitter.Exec(); + + threadA.Quit(); + threadB.Quit(); + threadC.Quit(); + + // Now, test data should be in dataD + RUNNER_ASSERT(BinaryQueueToString(dataD) == testData); +} diff --git a/tests/unused/test_shm.cpp b/tests/unused/test_shm.cpp new file mode 100644 index 0000000..20eed04 --- /dev/null +++ b/tests/unused/test_shm.cpp @@ -0,0 +1,1660 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_shm.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + * @brief Implementation file for test cases for shared data framework + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +using namespace DPL; + +namespace { +const SharedMemory::Key SHM_KEY = 12345; +const char* SEM_NAME = "/wrt_engine_shared_object_semaphore"; +const size_t VERSION = 1; + +const size_t MAX_THREADS = 10; +const size_t TEST_AND_SET_REPEATS = 100; + +const size_t SHARED_PROP_REPEATS = 3; + +const size_t SINGLETON_TEST_REPEATS = 3; + +// maximum random delay in singleton listener addition/removal +const size_t MAX_SINGLETON_LISTENER_DELAY = 50; + +const int SINGLE_PROCESS_REPEATS = 50; + +/* + * 5 seconds expected timeout for waitable events + * 30 seconds unexpected timeout for waitable events + * We don't want to block tests + */ +const size_t EXPECTED_WAITABLE_TIMEOUT = 5 * 1000; +const size_t UNEXPECTED_WAITABLE_TIMEOUT = 30 * 1000; + +bool g_enumTestCorrect = false; +bool g_enumTestIncorrect = false; +size_t g_delegateCalls = 0; + +void Wait(DPL::WaitableEvent& event, bool expectedTimeout = false) +{ + LogDebug("WaitForSingleHandle..."); + DPL::WaitableHandleIndexList list = DPL::WaitForSingleHandle( + event.GetHandle(), + expectedTimeout ? + EXPECTED_WAITABLE_TIMEOUT : UNEXPECTED_WAITABLE_TIMEOUT); + if (list.size() == 0) { + LogDebug("...timeout."); + } else { + LogDebug("...signaled."); + event.Reset(); + } + + if (expectedTimeout) { + RUNNER_ASSERT(list.size() == 0); + } else { + RUNNER_ASSERT(list.size() == 1); + } +} + +void RemoveIpcs() +{ + Try { + SharedMemory::Remove(SHM_KEY); + } + Catch(SharedMemory::Exception::RemoveFailed) { + // ignore + } + + Try { + DPL::Semaphore::Remove(SEM_NAME); + } + Catch(DPL::Semaphore::Exception::RemoveFailed) { + // ignore + } +} + +typedef DPL::TypeListDecl::Type TestTypeList; +typedef DPL::TypeListDecl::Type TestTypeList2; +typedef DPL::TypeListDecl::Type TestTypeList3; + +typedef SharedObject TestSharedObject; +typedef SharedObject TestSharedObject2; +typedef SharedObject TestSharedObject3; + +typedef std::shared_ptr TestSharedObjectPtr; + +const int INIT_EVENT = 0; +const int DESTROY_EVENT = 1; + +int g_values[TestTypeList::Size]; + +/* + * helper listening controller + */ +template +class ListeningController : + public DPL::Controller::Type> +{ + public: + explicit ListeningController(DPL::WaitableEvent* waitable); + ~ListeningController(); + + virtual void OnEventReceived(const int &event); + + virtual void OnEvent(const int /*event*/) {} + + protected: + std::shared_ptr m_so; + DPL::Thread m_thread; + DPL::WaitableEvent* m_waitable; +}; + +template +ListeningController::ListeningController( + DPL::WaitableEvent* waitable) : + m_waitable(waitable) +{ + Touch(); + m_thread.Run(); + SwitchToThread(&m_thread); + PostEvent(INIT_EVENT); +} + +template +ListeningController::~ListeningController() +{ + m_thread.Quit(); +} + +template +void ListeningController::OnEventReceived(const int& event) +{ + if (event == INIT_EVENT) { + m_so = SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + OnEvent(event); + m_waitable->Signal(); + } else if (event == DESTROY_EVENT) { + LogDebug("Destroying shared object"); + OnEvent(event); + + // deregister, destroy ad notify main thread + m_so.Reset(); + LogDebug("4"); + m_waitable->Signal(); + LogDebug("5"); + } else { + OnEvent(event); + } +} + +typedef DPL::TypeListDecl::Type SharedTypeList; + +class TestSharedObject4; +typedef std::shared_ptr TestSharedObject4Ptr; + +class TestSharedObject4 : public SharedObject +{ + public: + enum + { + SIZE_T, + BOOLEAN + }; + + static TestSharedObject4Ptr Create() + { + return SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + } + + ~TestSharedObject4() + { + LogDebug("dtor"); + } + + protected: + explicit TestSharedObject4(const std::string& semaphore) : + SharedObject(semaphore) + {} + + private: + void Init() + { + SetPropertyInternal(false); + } + friend class SharedObjectFactory; +}; +} // anonymus namespace + +////////////////////////////////////////////// + +RUNNER_TEST(SharedMemory_002_AccessByType) +{ + RemoveIpcs(); + + SharedData str; + + // access by type + str.Embedded<0, int>::value = 4; + str.Embedded<1, int>::value = 5; + str.Embedded<2, char>::value = 'd'; + str.Embedded<3, int[64]>::value[0] = 1; + str.Embedded<3, int[64]>::value[1] = 20; + + RUNNER_ASSERT((str.Embedded<0, int>::value) == 4); + RUNNER_ASSERT((str.Embedded<1, int>::value) == 5); + RUNNER_ASSERT((str.Embedded<2, char>::value) == 'd'); + RUNNER_ASSERT((str.Embedded<3, int[64]>::value[0]) == 1); + RUNNER_ASSERT((str.Embedded<3, int[64]>::value[1]) == 20); +} + +////////////////////////////////////////////// + +RUNNER_TEST(SharedMemory_003_AccessByIndex) +{ + RemoveIpcs(); + + SharedData str; + // access by enum + str.Embedded<0, TestTypeList::Element<0>::Type>::value = 4; + str.Embedded<1, TestTypeList::Element<1>::Type>::value = 5; + str.Embedded<2, TestTypeList::Element<2>::Type>::value = 'd'; + str.Embedded<3, TestTypeList::Element<3>::Type>::value[0] = 1; + str.Embedded<3, TestTypeList::Element<3>::Type>::value[1] = 20; + + RUNNER_ASSERT( + (str.Embedded<0, TestTypeList::Element<0>::Type>::value) == 4); + RUNNER_ASSERT( + (str.Embedded<1, TestTypeList::Element<1>::Type>::value) == 5); + RUNNER_ASSERT( + (str.Embedded<2, TestTypeList::Element<2>::Type>::value) == 'd'); + RUNNER_ASSERT( + (str.Embedded<3, TestTypeList::Element<3>::Type>::value[0]) == 1); + RUNNER_ASSERT( + (str.Embedded<3, TestTypeList::Element<3>::Type>::value[1]) == 20); +} + +////////////////////////////////////////////// + +RUNNER_TEST(SharedMemory_004_SimplifiedAccess) +{ + RemoveIpcs(); + + SharedData str; + + // access via PropertyRef + str.PropertyRef<1>() = 3; + RUNNER_ASSERT(str.PropertyRef<1>() == 3); + + int (&array)[64] = str.PropertyRef<3>(); + array[0] = 2; + RUNNER_ASSERT(str.PropertyRef<3>()[0] == 2); + + str.PropertyRef<3>()[1] = 19; + RUNNER_ASSERT(str.PropertyRef<3>()[1] == 19); + + // access via macro + str.SHARED_PROPERTY(0) = 2; + RUNNER_ASSERT(str.SHARED_PROPERTY(0) == 2); + + str.SHARED_PROPERTY(2) = 'c'; + RUNNER_ASSERT(str.SHARED_PROPERTY(2) == 'c'); + + str.SHARED_PROPERTY(3)[2] = 10; + RUNNER_ASSERT(str.SHARED_PROPERTY(3)[2] == 10); + + // old style check + RUNNER_ASSERT((str.Embedded<0, int>::value) == 2); + RUNNER_ASSERT((str.Embedded<1, int>::value) == 3); + RUNNER_ASSERT((str.Embedded<2, char>::value) == 'c'); + RUNNER_ASSERT((str.Embedded<3, int[64]>::value[0]) == 2); + RUNNER_ASSERT((str.Embedded<3, int[64]>::value[1]) == 19); + RUNNER_ASSERT((str.Embedded<3, int[64]>::value[2]) == 10); +} + +////////////////////////////////////////////// + +struct SharedStruct +{ + int a; + int b; + char c; + int d[64]; +}; + +typedef std::shared_ptr > SharedStructPtr; + +RUNNER_TEST(SharedMemory_010_BaseShmTest) +{ + RemoveIpcs(); + + typedef std::unique_ptr SharedMemoryPtr; + + // write + SharedMemoryPtr shm; + Try { + shm.Reset(SharedMemory::Create(SHM_KEY, false)); + } + Catch(SharedMemory::Exception::NotFound) { + shm.Reset(SharedMemory::Create(SHM_KEY, true, true)); + } + + SharedStructPtr str = shm->Attach(); + + str->Data()->a = 1; + str->Data()->b = 2; + str->Data()->c = '3'; + str->Data()->d[0] = 4; + str->Data()->d[1] = 5; + + // read + SharedMemoryPtr shm2; + Try { + shm2.Reset(SharedMemory::Create(SHM_KEY, false)); + } + Catch(SharedMemory::Exception::NotFound) { + shm2.Reset(SharedMemory::Create(SHM_KEY, true, true)); + } + + SharedStructPtr str2 = shm2->Attach(); + SharedStructPtr str3 = shm2->Attach(); + + RUNNER_ASSERT(str2->Data()->a == 1); + RUNNER_ASSERT(str2->Data()->b == 2); + RUNNER_ASSERT(str2->Data()->c == '3'); + RUNNER_ASSERT(str2->Data()->d[0] == 4); + RUNNER_ASSERT(str2->Data()->d[1] == 5); + + RUNNER_ASSERT(str3->Data()->a == 1); + RUNNER_ASSERT(str3->Data()->b == 2); + RUNNER_ASSERT(str3->Data()->c == '3'); + RUNNER_ASSERT(str3->Data()->d[0] == 4); + RUNNER_ASSERT(str3->Data()->d[1] == 5); + + str2->Data()->b = 4; + str2->Data()->c = 'c'; + str2->Data()->d[0] = 0; + RUNNER_ASSERT(str3->Data()->a == 1); + RUNNER_ASSERT(str3->Data()->b == 4); + RUNNER_ASSERT(str3->Data()->c == 'c'); + RUNNER_ASSERT(str3->Data()->d[0] == 0); + RUNNER_ASSERT(str3->Data()->d[1] == 5); +} + +////////////////////////////////////////////// + +RUNNER_TEST(SharedMemory_020_SharedObjectTest) +{ + RemoveIpcs(); + + typedef SharedObject MySharedObj; + + MySharedObj::Ptr so = + SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + + RUNNER_ASSERT((so->GetProperty<0, size_t>()) == 0); + so->SetProperty<0, size_t>(4); + RUNNER_ASSERT((so->GetProperty<0, size_t>()) == 4); +} + +////////////////////////////////////////////// + +class InitTestSharedObject : public TestSharedObject +{ + protected: + explicit InitTestSharedObject(const std::string& semaphore) : + TestSharedObject(semaphore) {} + + virtual void Init(); // from SharedObject + + private: + friend class SharedObjectFactory; +}; + +void InitTestSharedObject::Init() +{ + SetPropertyInternal<0>(1); + SetPropertyInternal<1>(2); + SetPropertyInternal<2>('c'); +} + +RUNNER_TEST(SharedMemory_021_InitTest) +{ + RemoveIpcs(); // we need non existing shm + + std::shared_ptr sho = + SharedObjectFactory::Create( + SHM_KEY, SEM_NAME); + RUNNER_ASSERT((sho->GetProperty<0, int>()) == 1); + RUNNER_ASSERT((sho->GetProperty<1, int>()) == 2); + RUNNER_ASSERT((sho->GetProperty<2, char>()) == 'c'); +} + +////////////////////////////////////////////// + +class VersionTestSO1 : public TestSharedObject +{ + protected: + explicit VersionTestSO1(const std::string& semaphore) : + TestSharedObject(semaphore) {} + + virtual SizeType GetVersion() const + { + return 1; + } // from SharedObject + + private: + friend class SharedObjectFactory; +}; + +class VersionTestSO2 : public TestSharedObject +{ + protected: + explicit VersionTestSO2(const std::string& semaphore) : + TestSharedObject(semaphore) {} + + virtual SizeType GetVersion() const + { + return 2; + } // from SharedObject + + private: + friend class SharedObjectFactory; +}; + +RUNNER_TEST(SharedMemory_022_InvalidVersionTest) +{ + RemoveIpcs(); // we need non existing shm + + std::shared_ptr sho = + SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + + Try { + std::shared_ptr sho2 = + SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + + RUNNER_ASSERT_MSG(false, "Invalid shm version has been accepted"); + } + Catch(SharedObjectBase::Exception::InvalidVersion) { + RUNNER_ASSERT(true); + } +} + +////////////////////////////////////////////// + +RUNNER_TEST(SharedMemory_023_InvalidSizeTest) +{ + RemoveIpcs(); // we need non existing shm + + typedef SharedObject SO1; + typedef SharedObject SO2; + + SO1::Ptr sho = SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + + Try { + SO2::Ptr sho2 = SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + + RUNNER_ASSERT_MSG(false, "Invalid shm size has been accepted"); + } + Catch(SharedObjectBase::Exception::InvalidSize) { + RUNNER_ASSERT(true); + } +} + +////////////////////////////////////////////// + +class MagicTestSO1 : public TestSharedObject +{ + protected: + explicit MagicTestSO1(const std::string& semaphore) : + TestSharedObject(semaphore) {} + + // from SharedObject + virtual MagicType GetMagicNumber() const + { + return 661; + } + + private: + friend class SharedObjectFactory; +}; + +class MagicTestSO2 : public TestSharedObject +{ + protected: + explicit MagicTestSO2(const std::string& semaphore) : + TestSharedObject(semaphore) {} + + // from SharedObject + virtual MagicType GetMagicNumber() const + { + return 662; + } + + private: + friend class SharedObjectFactory; +}; + +RUNNER_TEST(SharedMemory_024_InvalidMagicTest) +{ + RemoveIpcs(); // we need non existing shm + + std::shared_ptr sho = + SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + + Try { + std::shared_ptr sho2 = + SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + + RUNNER_ASSERT_MSG(false, "Invalid shm magic number has been accepted"); + } + Catch(SharedObjectBase::Exception::InvalidMagicNumber) { + RUNNER_ASSERT(true); + } +} + +////////////////////////////////////////////// + +/* + * Listening shared object + */ +class EnumTestSO1 : public TestSharedObject +{ + public: + void SetWaitable(DPL::WaitableEvent* waitable) + { + m_waitable = waitable; + } + + protected: + explicit EnumTestSO1(const std::string& semaphore) : + TestSharedObject(semaphore), + m_waitable(NULL) + {} + + + virtual void PropertyChanged(size_t propertyEnum); + + private: + friend class SharedObjectFactory; + + DPL::WaitableEvent* m_waitable; +}; + +void EnumTestSO1::PropertyChanged(size_t propertyEnum) +{ + if (propertyEnum == 1) { + LogDebug("Property enum " << propertyEnum << " correctly set"); + g_enumTestCorrect = true; + } + if (propertyEnum == 4) { + // This is bad. We only have 4 types + LogError("Property enum " << propertyEnum << " should be skipped"); + g_enumTestIncorrect = true; + } + // confirm property change notification + m_waitable->Signal(); +} + +class EnumController : public ListeningController +{ + public: + explicit EnumController(DPL::WaitableEvent* waitable) : + ListeningController(waitable) {} + + virtual void OnEvent(const int event); +}; + +void EnumController::OnEvent(const int event) +{ + if (event == INIT_EVENT) { + m_so->SetWaitable(m_waitable); + } +} + +/* + * Writing shared object with correct size but different number of types + */ +class EnumTestSO2 : public TestSharedObject3 +{ + protected: + explicit EnumTestSO2(const std::string& semaphore) : + TestSharedObject3(semaphore) {} + + private: + friend class SharedObjectFactory; +}; + +RUNNER_TEST(SharedMemory_025_InvalidEnumTest) +{ + RemoveIpcs(); // we need non existing shm + + g_enumTestCorrect = false; + g_enumTestIncorrect = false; + + DPL::WaitableEvent waitable; + + // create listening controller and wait until it registers + EnumController controller(&waitable); + Wait(waitable); + LogDebug("Listening controller created"); + + // create writing shared object + std::shared_ptr sho2 = + SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + DPL::WaitableHandleIndexList list; + + // write property and wait for confirmation + sho2->SetProperty<1>(2); + Wait(waitable); + + // write incorrect property and wait for confirmation + // we expect timeout + sho2->SetProperty<4>(2); + Wait(waitable, true); + + // schedule listener deregistration and wait for confirmation + controller.PostEvent(DESTROY_EVENT); + Wait(waitable); + + // check results + RUNNER_ASSERT(g_enumTestCorrect == true); + RUNNER_ASSERT(g_enumTestIncorrect == false); +} + +////////////////////////////////////////////// + +class MultiThreadSO : public TestSharedObject +{ + public: + void TestAndSetProperty(); + + protected: + explicit MultiThreadSO(const std::string& semaphore) : + TestSharedObject(semaphore) {} + + private: + friend class SharedObjectFactory; +}; + +void MultiThreadSO::TestAndSetProperty() +{ + ScopedFlaggedLock lock(*this); + + int value = PropertyRef<0, int>(); + DPL::Thread::MicroSleep(100); + SetPropertyInternal<0>(value + 1); +} + +class ShmController : public ListeningController +{ + public: + explicit ShmController(DPL::WaitableEvent* event) : + ListeningController(event), m_counter(0) + {} + + virtual void OnEventReceived(const int& event); + + private: + size_t m_counter; +}; + +void ShmController::OnEventReceived(const int& event) +{ + if (event == INIT_EVENT) { + m_so = SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + PostEvent(2); + } else if (event == DESTROY_EVENT) { + LogDebug("Destroying shared object"); + // deregister, destroy ad notify main thread + m_so.Reset(); + m_waitable->Signal(); + } else if (event == 2) { + m_so->TestAndSetProperty(); + m_counter++; + if (m_counter >= TEST_AND_SET_REPEATS) { + LogDebug("Max tests reached. Finishing thread"); + PostEvent(DESTROY_EVENT); + return; + } + PostEvent(2); + } +} + +RUNNER_TEST(SharedMemory_030_MultithreadTest) +{ + RemoveIpcs(); // we need non existing shm + + typedef SharedObject SHO; + SHO::Ptr sho = SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + + ShmController* controller[MAX_THREADS]; + DPL::WaitableEvent finalEvent[MAX_THREADS]; + + for (size_t i = 0; i < MAX_THREADS; ++i) { + controller[i] = new ShmController(&finalEvent[i]); + } + + for (size_t i = 0; i < MAX_THREADS; ++i) { + Wait(finalEvent[i]); + } + + for (size_t i = 0; i < MAX_THREADS; ++i) { + delete controller[i]; + controller[i] = NULL; + } + + int value = sho->GetProperty<0, int>(); + LogDebug("Final value is " << value << ", expected " << + MAX_THREADS * TEST_AND_SET_REPEATS); + RUNNER_ASSERT(value == MAX_THREADS * TEST_AND_SET_REPEATS); +} + +////////////////////////////////////////////// + +class MyModel10 : public DPL::Model +{ + public: + explicit MyModel10(const TestSharedObject4Ptr& shared_object) : + DPL::Model(), boolValue(this, shared_object) {} + + SharedProperty + boolValue; +}; + +/* + * Listening controller + */ +class ShmController3 : public ListeningController +{ + public: + explicit ShmController3(DPL::WaitableEvent* event) : + ListeningController(event) + {} + + virtual void OnEvent(const int event); + + void OnValueChanged(const DPL::PropertyEvent& event); + + private: + typedef std::unique_ptr MyModelPtr; + + // model with property bound to shared object + MyModelPtr m_model; +}; + +void ShmController3::OnEvent(const int event) +{ + if (event == INIT_EVENT) { + m_model.Reset(new MyModel10(m_so)); + m_model->boolValue.AddListener( + std::bind(&ShmController3::OnValueChanged, this)); + } else if (event == DESTROY_EVENT) { + m_model->boolValue.RemoveListener( + std::bind(&ShmController3::OnValueChanged, this)); + m_model.Reset(); + } +} + +void ShmController3::OnValueChanged(const DPL::PropertyEvent& event) +{ + if (event.value) { + // change back + m_model->boolValue.Set(false); + } else { + LogError("Expected value = true, got false"); + } + + m_waitable->Signal(); +} + +RUNNER_TEST(SharedMemory_050_SharedProperty) +{ + RemoveIpcs(); + + bool result = true; + DPL::WaitableEvent waitable; + // listener controller + ShmController3 controller(&waitable); + Wait(waitable); + + TestSharedObject4Ptr sharedObject = TestSharedObject4::Create(); + + for (size_t i = 0; i < SHARED_PROP_REPEATS; ++i) { + sharedObject->SetProperty(true); + Wait(waitable); + result = sharedObject->GetProperty(); + RUNNER_ASSERT(result == false); + } + controller.PostEvent(DESTROY_EVENT); + Wait(waitable); +} + +////////////////////////////////////////////// + +class MyModel2 : public DPL::Model +{ + public: + explicit MyModel2(const TestSharedObjectPtr& shared_object) : + counter(this, shared_object) {} + + SharedProperty counter; +}; + +class SPController : public ListeningController +{ + public: + explicit SPController(DPL::WaitableEvent* event) : + ListeningController(event), m_repeats(1) {} + + virtual void OnEvent(const int event); + + void OnValueChanged1(const DPL::PropertyEvent& event); + void OnValueChanged2(const DPL::PropertyEvent& event); + + private: + std::unique_ptr m_model1; + std::unique_ptr m_model2; + + int m_repeats; + std::shared_ptr m_so2; +}; + +void SPController::OnEvent(const int event) +{ + if (event == INIT_EVENT) { + m_so2 = SharedObjectFactory::Create(SHM_KEY, + SEM_NAME); + + // create and register 2 models sharing the same property + m_model1.Reset(new MyModel2(m_so)); + m_model2.Reset(new MyModel2(m_so2)); + m_model1->counter.AddListener( + std::bind(&SPController::OnValueChanged1, this)); + m_model2->counter.AddListener( + std::bind(&SPController::OnValueChanged2, this)); + m_model1->counter.Set(1); + } else if (event == DESTROY_EVENT) { + m_model1->counter.RemoveListener( + std::bind(&SPController::OnValueChanged1, this)); + m_model2->counter.RemoveListener( + std::bind(&SPController::OnValueChanged2, this)); + + m_model1.Reset(); + m_model2.Reset(); + m_so2.Reset(); + } +} + +void SPController::OnValueChanged1(const DPL::PropertyEvent& event) +{ + if (m_repeats >= SINGLE_PROCESS_REPEATS) { + PostEvent(DESTROY_EVENT); + return; + } + + LogDebug("[1] Value changed to " << event.value); + m_repeats++; + m_model1->counter.Set(event.value + 1); +} + +void SPController::OnValueChanged2(const DPL::PropertyEvent& event) +{ + if (m_repeats >= SINGLE_PROCESS_REPEATS) { + PostEvent(DESTROY_EVENT); + return; + } + + LogDebug("[2] Value changed to " << event.value); + m_repeats++; + m_model2->counter.Set(event.value + 1); +} + +RUNNER_TEST(SharedMemory_060_SingleProcess) +{ + RemoveIpcs(); + + DPL::WaitableEvent waitable; + SPController controller(&waitable); + TestSharedObjectPtr sho = SharedObjectFactory::Create( + SHM_KEY, + SEM_NAME); + + // wait for creation + Wait(waitable); + + // wait for destruction + Wait(waitable); + + int value = sho->GetProperty<0, int>(); + + LogDebug("final value: " << value); + + // check value + RUNNER_ASSERT(value == SINGLE_PROCESS_REPEATS); +} + +////////////////////////////////////////////// + +class ListenerTestController : public ListeningController, + public ISharedObjectListener<0, int>, + public ISharedObjectListener<1, int>, + public ISharedObjectListener<2, char>, + public ISharedObjectListener<3, int[64]> +{ + public: + explicit ListenerTestController(DPL::WaitableEvent* event) : + ListeningController(event) {} + + ~ListenerTestController(); + + virtual void OnEvent(const int event); + + virtual void ValueChanged(size_t propertyEnum, + const int& value, + const void* info = NULL); + virtual void ValueChanged(size_t propertyEnum, + const char& value, + const void* info = NULL); + virtual void ValueChanged(size_t propertyEnum, + const int(&value)[64], + const void* info = NULL); +}; + +ListenerTestController::~ListenerTestController() +{} + +void ListenerTestController::OnEvent(const int event) +{ + if (event == INIT_EVENT) { + // add self as a listener to shared object + m_so->AddListener<0, int>(this); + m_so->AddListener<1, int>(this); + m_so->AddListener<2, char>(this); + m_so->AddListener<3, int[64]>(this); + } else if (event == DESTROY_EVENT) { + // remove self from listener list + m_so->RemoveListener<0, int>(this); + m_so->RemoveListener<1, int>(this); + m_so->RemoveListener<2, char>(this); + m_so->RemoveListener<3, int[64]>(this); + } +} + +void ListenerTestController::ValueChanged(size_t propertyEnum, + const int& value, + const void* /*info*/) +{ + LogDebug("ValueChanged(int) " << propertyEnum << " " << value); + if ((propertyEnum == 0 && + value == 1) || (propertyEnum == 1 && value == 2)) + { + g_values[propertyEnum]++; + if (g_values[propertyEnum] == 3) { + m_waitable->Signal(); + } + } +} + +void ListenerTestController::ValueChanged(size_t propertyEnum, + const char& value, + const void* /*info*/) +{ + LogDebug("ValueChanged(char) " << propertyEnum << " " << value); + if (propertyEnum == 2 && value == 'c') { + g_values[propertyEnum]++; + if (g_values[propertyEnum] == 3) { + m_waitable->Signal(); + } + } +} + +void ListenerTestController::ValueChanged(size_t propertyEnum, + const int(&value)[64], + const void* /*info*/) +{ + LogDebug("ValueChanged(int[64]) " << propertyEnum << " " << value[5]); + if (propertyEnum == 3 && value[5] == 5) { + g_values[propertyEnum]++; + if (g_values[propertyEnum] == 3) { + m_waitable->Signal(); + } + } +} + +RUNNER_TEST(SharedMemory_070_SharedObjectListeners) +{ + RemoveIpcs(); + + // setup global flags + for (size_t i = 0; i < TestTypeList::Size; ++i) { + g_values[i] = 0; + } + + // create shared object + TestSharedObjectPtr sho = SharedObjectFactory::Create( + SHM_KEY, SEM_NAME); + + // create 1st listener and wait for it + DPL::WaitableEvent waitable; + ListenerTestController c1(&waitable); + Wait(waitable); + + // create 2nd listener and wait for it + ListenerTestController c2(&waitable); + Wait(waitable); + + // create 3rd listener and wait for it + ListenerTestController c3(&waitable); + Wait(waitable); + + // set properties and wait for result + sho->SetProperty<0, int>(1); + Wait(waitable); + + RUNNER_ASSERT(g_values[0] == 3); + + sho->SetProperty<1, int>(2); + Wait(waitable); + + RUNNER_ASSERT(g_values[1] == 3); + + sho->SetProperty<2, char>('c'); + Wait(waitable); + + RUNNER_ASSERT(g_values[2] == 3); + + int array[64]; + memset(array, 0, 64 * sizeof(array[0])); + array[5] = 5; + sho->SetProperty<3, int[64]>(array); + Wait(waitable); + + RUNNER_ASSERT(g_values[3] == 3); + + // finalize listeners + c1.PostEvent(DESTROY_EVENT); + Wait(waitable); + + c2.PostEvent(DESTROY_EVENT); + Wait(waitable); + + c3.PostEvent(DESTROY_EVENT); + Wait(waitable); +} + +////////////////////////////////////////////// + +/* + * class simulating DB access + */ +class DAO : public DPL::Noncopyable +{ + public: + DAO() : m_boolValue(false) {} + + void SetBoolValue(const bool& value) + { + m_boolValue = value; + } + + bool GetBoolValue() const + { + return m_boolValue; + } + + private: + bool m_boolValue; +}; + +/* + * Model with property having set delegate defined + */ +class MyModel3 : public DPL::Model +{ + public: + typedef SharedPropertyEx PropertyType; + + MyModel3(const TestSharedObject4Ptr& shared_object, DAO* dao) : + boolValue(this, + shared_object, + PropertyType::SetDelegate(dao, &DAO::SetBoolValue)) + {} + + PropertyType boolValue; +}; + +RUNNER_TEST(SharedMemory_090_SetPropertyDelegate) +{ + RemoveIpcs(); + + // dao object + DAO dao; + + // create shared object + TestSharedObject4Ptr sho = TestSharedObject4::Create(); + + // set property but call dao delegate within semaphore + sho->SetProperty( + true, + MyModel3::PropertyType::SetDelegate(&dao, &DAO::SetBoolValue)); + + // check dao value + RUNNER_ASSERT(dao.GetBoolValue() == true); + + // check shared object value + bool shoValue = sho->GetProperty(); + RUNNER_ASSERT(shoValue == true); + + // try the same with shared property + MyModel3 model(sho, &dao); + + // set property + model.boolValue.Set(false); + + // check dao value + RUNNER_ASSERT(dao.GetBoolValue() == false); + + // check sho value + shoValue = sho->GetProperty(); + RUNNER_ASSERT(shoValue == false); + + // check property value + RUNNER_ASSERT(model.boolValue.Get() == false); +} + +////////////////////////////////////////////// + +/* + * Lazy initialization test shared object + */ +class LazySharedObject : public SharedObject +{ + private: + LazySharedObject() : + m_read(false) + {} + + public: + explicit LazySharedObject(const std::string& semaphore) : + SharedObject(semaphore) + , m_read(false) + {} + + void Init(); + + bool IsRead() const + { + return m_read; + } + + private: + friend class SharedObjectFactory; + + bool m_read; +}; + +void LazySharedObject::Init() +{ + SetPropertyInternal<0>(42); + m_read = true; +} + +RUNNER_TEST(SharedMemory_100_LazyInit) +{ + RemoveIpcs(); + + typedef std::shared_ptr LazySharedObjectPtr; + + // create shared object + LazySharedObjectPtr sho = SharedObjectFactory::Create( + SHM_KEY, SEM_NAME); + + RUNNER_ASSERT(sho->IsRead() == false); + + // get property causing lazy init + int value = sho->GetProperty<0, int>(); + + RUNNER_ASSERT(sho->IsRead() == true); + RUNNER_ASSERT(value == 42); + + // create another object + LazySharedObjectPtr sho2 = SharedObjectFactory::Create( + SHM_KEY, SEM_NAME); + + RUNNER_ASSERT(sho2->IsRead() == false); + + // get property NOT causing lazy init + value = sho2->GetProperty<0, int>(); + + RUNNER_ASSERT(sho2->IsRead() == false); + RUNNER_ASSERT(value == 42); + + // destroy both objects + sho.Reset(); + sho2.Reset(); + + // create shared object + LazySharedObjectPtr sho3 = SharedObjectFactory::Create( + SHM_KEY, SEM_NAME); + + RUNNER_ASSERT(sho3->IsRead() == false); + + // set property causing lazy init + sho3->SetProperty<0>(43); + value = sho3->GetProperty<0, int>(); + + RUNNER_ASSERT(sho3->IsRead() == true); + RUNNER_ASSERT(value == 43); +} + +////////////////////////////////////////////// + +bool SetCondition(const int& readValue, int& setValue); +bool SetCondition(const int& readValue, int& setValue) +{ + LogDebug("Condition delegate called with read value = " << readValue << + " and set value = " << setValue); + + if (readValue > 3) { + LogDebug("Condition is false"); + return false; + } + + LogDebug("Condition is true"); + if (4 == setValue) { + setValue = 10; + LogDebug("Changing set value to " << setValue); + } + return true; +} + +void SetDelegate(const int& readValue); +void SetDelegate(const int& readValue) +{ + LogDebug("Set delegate called " << readValue); + g_delegateCalls++; +} + +RUNNER_TEST(SharedMemory_120_ConditionalSet) +{ + RemoveIpcs(); + + TestSharedObjectPtr sho = SharedObjectFactory::Create( + SHM_KEY, + SEM_NAME); + + g_delegateCalls = 0; + + RUNNER_ASSERT(0 == (sho->GetProperty<0, int>())); + + std::function condition = SetCondition; + std::function delegate = SetDelegate; + + bool succeeded = false; + + succeeded = sho->ConditionalSetProperty<0>(-2, condition); + + RUNNER_ASSERT(succeeded); + RUNNER_ASSERT(-2 == (sho->GetProperty<0, int>())); + + succeeded = sho->ConditionalSetProperty<0>(4, condition, delegate); + + RUNNER_ASSERT(succeeded); + RUNNER_ASSERT(10 == (sho->GetProperty<0, int>())); + RUNNER_ASSERT(1 == g_delegateCalls); + + succeeded = sho->ConditionalSetProperty<0>(5, condition); + + RUNNER_ASSERT(!succeeded); + RUNNER_ASSERT(10 == (sho->GetProperty<0, int>())); + + succeeded = sho->ConditionalSetProperty<0>(666, condition, delegate); + + RUNNER_ASSERT(!succeeded); + RUNNER_ASSERT(10 == (sho->GetProperty<0, int>())); + RUNNER_ASSERT(1 == g_delegateCalls); +} + +////////////////////////////////////////////// + +/* + * Shared object used by multiple threads as a singleton. + */ +class MTSharedObject : public SharedObject +{ + public: + explicit MTSharedObject(const std::string& semaphore) : + SharedObject(semaphore) + {} + + void Clear(); + + private: + friend class SharedObjectFactory; +}; + +typedef std::shared_ptr MTSharedObjectPtr; + +void MTSharedObject::Clear() +{ + int array[64] = {}; + SetProperty<0>(0); + SetProperty<1>(0); + SetProperty<2>(static_cast(0)); + SetProperty<3>(array); +} + +/* + * Shared object singleton + */ +class SharedObjectSingleton +{ + public: + static MTSharedObjectPtr Instance(); + static void Destroy(); + + private: + static MTSharedObjectPtr m_sho; + static DPL::Mutex m_mutex; +}; + +MTSharedObjectPtr SharedObjectSingleton::m_sho; +DPL::Mutex SharedObjectSingleton::m_mutex; + +MTSharedObjectPtr SharedObjectSingleton::Instance() +{ + DPL::Mutex::ScopedLock lock(&m_mutex); + if (!m_sho) { + m_sho = SharedObjectFactory::Create(SHM_KEY, SEM_NAME); + } + return m_sho; +} + +void SharedObjectSingleton::Destroy() +{ + DPL::Mutex::ScopedLock lock(&m_mutex); + m_sho.Reset(); +} + +/* + * Listening controller + */ +class ShmController4 : public ListeningController, + public ISharedObjectListener<0, int>, + public ISharedObjectListener<1, int>, + public ISharedObjectListener<2, char>, + public ISharedObjectListener<3, int[64]> +{ + public: + enum { + ADD_LISTENERS = 2, + REMOVE_LISTENERS = 3, + DESTROY_SINGLETON = 4 + }; + + explicit ShmController4(DPL::WaitableEvent* event) : + ListeningController(event), + m_counter(0) + {} + + virtual void OnEventReceived(const int& event); + + virtual void ValueChanged(size_t propertyEnum, + const int& value, + const void* info = NULL); + virtual void ValueChanged(size_t propertyEnum, + const char& value, + const void* info = NULL); + virtual void ValueChanged(size_t propertyEnum, + const int(&value)[64], + const void* info = NULL); + + bool NotRegistered(); + + private: + void Sleep(); + + size_t m_counter; + static unsigned int seed = time(NULL); +}; + +void ShmController4::ValueChanged(size_t propertyEnum, + const int& value, + const void* /*info*/) +{ + LogDebug("ValueChanged(int) " << propertyEnum << " " << value); + if ((propertyEnum == 0 && value == 1) || + (propertyEnum == 1 && value == 11)) + { + m_waitable->Signal(); + } +} + +void ShmController4::ValueChanged(size_t propertyEnum, + const char& value, + const void* /*info*/) +{ + LogDebug("ValueChanged(char) " << propertyEnum << " " << value); + if (propertyEnum == 2 && value == 'a') { + m_waitable->Signal(); + } +} + +void ShmController4::ValueChanged(size_t propertyEnum, + const int(&value)[64], + const void* /*info*/) +{ + LogDebug("ValueChanged(int[64]) " << propertyEnum << " " << value[5]); + if (propertyEnum == 3 && value[0] == 0 && value[1] == 1 && value[2] == 2) { + m_waitable->Signal(); + } +} + +void ShmController4::Sleep() +{ + DPL::Thread::GetCurrentThread()->MiliSleep( + rand_r(&seed) % MAX_SINGLETON_LISTENER_DELAY); +} + +void ShmController4::OnEventReceived(const int& event) +{ + switch (event) { + case INIT_EVENT: + m_so = SharedObjectSingleton::Instance(); + m_waitable->Signal(); + break; + + case DESTROY_EVENT: + LogDebug("Destroying shared object"); + // deregister, destroy and notify main thread + m_so.Reset(); + m_waitable->Signal(); + break; + + case ADD_LISTENERS: + // add listener and notify + m_so->AddListener<0, int>(this); + Sleep(); + m_so->AddListener<1, int>(this); + Sleep(); + m_so->AddListener<2, char>(this); + Sleep(); + m_so->AddListener<3, int[64]>(this); + Sleep(); + m_waitable->Signal(); + break; + + case REMOVE_LISTENERS: + // remove listener and notify + m_so->RemoveListener<0, int>(this); + Sleep(); + m_so->RemoveListener<1, int>(this); + Sleep(); + m_so->RemoveListener<2, char>(this); + Sleep(); + m_so->RemoveListener<3, int[64]>(this); + Sleep(); + m_waitable->Signal(); + break; + + case DESTROY_SINGLETON: + SharedObjectSingleton::Destroy(); + m_waitable->Signal(); + break; + + default: + LogError("Unsupported event received: " << event); + } +} + +void MultipleWait(DPL::WaitableEvent(&event)[MAX_THREADS]); +void MultipleWait(DPL::WaitableEvent(&event)[MAX_THREADS]) +{ + for (size_t i = 0; i < MAX_THREADS; ++i) { + Wait(event[i]); + } +} + +/* + * Try to remove property listener. If there's no such listener an exception + * should be thrown. + */ +#define LISTENER_ASSERT(property) \ + Try { \ + singleton->RemoveListener<(property)>(controller[i]); \ + LogError("Controller " << i << " is still listening for property " \ + << #property); \ + RUNNER_ASSERT_MSG(false, "No listeners expected"); \ + } \ + Catch(MTSharedObject::Exception::ListenerNotFound) { \ + RUNNER_ASSERT(true); \ + } \ + +// test +RUNNER_TEST(SharedMemory_130_SharedObjectSingleton) +{ + RemoveIpcs(); // we need non existing shm + + // writer shared object + TestSharedObjectPtr sho = SharedObjectFactory::Create( + SHM_KEY, SEM_NAME); + + ShmController4* controller[MAX_THREADS]; + DPL::WaitableEvent waitable[MAX_THREADS]; + + const int array[64] = { 0, 1, 2 }; + + // Create and wait for notification. Make sure that the thread/controller 0 + // is created first + LogDebug("Creating controllers"); + for (size_t i = 0; i < MAX_THREADS; ++i) { + controller[i] = new ShmController4(&waitable[i]); + Wait(waitable[i]); + } + + // singleton will be created by thread/controller 0 by now + MTSharedObjectPtr singleton = SharedObjectSingleton::Instance(); + + for (size_t repeats = 0; repeats < SINGLETON_TEST_REPEATS; ++repeats) { + LogDebug("%%%%%%%%%%%%%%%%%%%%%"); + LogDebug("Iteration " << repeats + 1 << " of " << SINGLETON_TEST_REPEATS); + singleton->Clear(); + + // add listeners + LogDebug("Adding listeners"); + for (size_t i = 0; i < MAX_THREADS; ++i) { + controller[i]->PostEvent(ShmController4::ADD_LISTENERS); + } + // wait for listeners + MultipleWait(waitable); + + RUNNER_ASSERT((singleton->GetProperty<0, int>()) == 0); + RUNNER_ASSERT((singleton->GetProperty<1, int>()) == 0); + RUNNER_ASSERT((singleton->GetProperty<2, char>()) == 0); + + int checkArray[64] = {}; + singleton->GetProperty<3>(checkArray); + RUNNER_ASSERT(checkArray[0] == 0); + RUNNER_ASSERT(checkArray[1] == 0); + RUNNER_ASSERT(checkArray[2] == 0); + + // change + LogDebug("Setting property 0"); + sho->SetProperty<0>(1); + // wait for confirmations + MultipleWait(waitable); + + // change + LogDebug("Setting property 1"); + sho->SetProperty<1>(11); + // wait for confirmations + MultipleWait(waitable); + + // change + LogDebug("Setting property 2"); + sho->SetProperty<2>('a'); + // wait for confirmations + MultipleWait(waitable); + + // change + LogDebug("Setting property 3"); + sho->SetProperty<3>(array); + // wait for confirmations + MultipleWait(waitable); + + // remove listeners + LogDebug("Removing listeners"); + for (size_t i = 0; i < MAX_THREADS; ++i) { + controller[i]->PostEvent(ShmController4::REMOVE_LISTENERS); + } + // wait for listeners + MultipleWait(waitable); + + // check if listeners array is empty + LogDebug("Checking listeners"); + for (size_t i = 0; i < MAX_THREADS; ++i) { + LISTENER_ASSERT(0); + LISTENER_ASSERT(1); + LISTENER_ASSERT(2); + LISTENER_ASSERT(3); + } + + RUNNER_ASSERT((singleton->GetProperty<0, int>()) == 1); + RUNNER_ASSERT((singleton->GetProperty<1, int>()) == 11); + RUNNER_ASSERT((singleton->GetProperty<2, char>()) == 'a'); + singleton->GetProperty<3>(checkArray); + RUNNER_ASSERT(checkArray[0] == 0); + RUNNER_ASSERT(checkArray[1] == 1); + RUNNER_ASSERT(checkArray[2] == 2); + } + + singleton.Reset(); + + // Destroy controllers and wait for confirmation. Make sure that + // thread/controller 0 is destroyed in the end + LogDebug("Destroying controllers"); + for (int i = MAX_THREADS - 1; i >= 0; --i) { + controller[i]->PostEvent(DESTROY_EVENT); + Wait(waitable[i]); + if (i == 0) { + /* + * Destroy singleton before thread that created it finishes. + * This is to properly close all waitable handles opened by + * SharedObject in thread 0. + */ + LogDebug("Destroying singleton"); + controller[i]->PostEvent(ShmController4::DESTROY_SINGLETON); + Wait(waitable[i]); + } + delete controller[i]; + } +} + +#undef LISTENER_ASSERT + +/* + * test preconditions & postconditions: + * - no existing shared memory with given SHM_KEY + * - no existing semaphore of given SEM_NAME + */ +RUNNER_TEST(SharedMemory_001_Preconditions) { + RemoveIpcs(); +} + +RUNNER_TEST(SharedMemory_999_Postconditions) { + RemoveIpcs(); +} diff --git a/tests/unused/test_sql_connection.cpp b/tests/unused/test_sql_connection.cpp new file mode 100644 index 0000000..bc2b7e0 --- /dev/null +++ b/tests/unused/test_sql_connection.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_sql_connection.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of sql connection tests + */ + +/* + * + * This test has been saved from original test_sql_connection.cpp in wrt-commons + * project. + * + */ + +#include + +RUNNER_TEST(SqlConnection_MassiveReadWrite_SemaphoreSynchronization) +{ + std::ostringstream dbSemaporeFileNameStream; + unsigned int seed = time(NULL); + + dbSemaporeFileNameStream << "dpl_tests_dbso_sem_"; + dbSemaporeFileNameStream << rand_r(&seed) << ".sem"; + + std::string dbSemaphoreFileName = dbSemaporeFileNameStream.str(); + + SemaphoreSynchronizationObjectGenerator m_generator(dbSemaphoreFileName); + MassiveReadWriteTest(&m_generator); +} diff --git a/tests/unused/test_task.cpp b/tests/unused/test_task.cpp new file mode 100644 index 0000000..a885dcd --- /dev/null +++ b/tests/unused/test_task.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_task.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of task tests + */ +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL) + +class MySingleTask : + public DPL::TaskDecl +{ + protected: + void StepOne() + {} + + public: + MySingleTask() : + DPL::TaskDecl(this) + { + AddStep(&MySingleTask::StepOne); + } +}; + +class MyMultiTask : + public DPL::MultiTaskDecl +{ + protected: + typedef DPL::MultiTaskDecl BaseType; + + void StepOne() + { + LogDebug("Step one"); + } + + void StepTwo() + { + LogDebug("Step two"); + } + + void StepThree() + { + LogDebug("Step three"); + } + + public: + MyMultiTask() : + BaseType(this, 2) + { + BaseType::StepList depListStepThree; + depListStepThree.push_back(&MyMultiTask::StepOne); + depListStepThree.push_back(&MyMultiTask::StepTwo); + AddStep(&MyMultiTask::StepThree, depListStepThree); + + BaseType::StepList depListStepTwo; + depListStepTwo.push_back(&MyMultiTask::StepOne); + AddStep(&MyMultiTask::StepTwo, depListStepTwo); + + BaseType::StepList depListStepOne; + AddStep(&MyMultiTask::StepOne, depListStepOne); + } +}; + +RUNNER_TEST(Task_SingleTask) +{ + MySingleTask task; + while (task.NextStep()) {} +} + +RUNNER_TEST(Task_MultiTask) +{ + MyMultiTask task; + while (task.NextStep()) {} +} diff --git a/tests/utils/CMakeLists.txt b/tests/utils/CMakeLists.txt new file mode 100644 index 0000000..f17421b --- /dev/null +++ b/tests/utils/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) +# @version 1.0 +# @brief +# + +SET(TARGET_NAME "wrt-commons-tests-utils") + +# Set DPL tests sources +SET(DPL_TESTS_UTIL_SOURCES + ${TESTS_DIR}/utils/main.cpp + ${TESTS_DIR}/utils/widget_version.cpp + ${TESTS_DIR}/utils/bash_utils.cpp + ${TESTS_DIR}/utils/wrt_utility.cpp + ${TESTS_DIR}/utils/path_tests.cpp +) + +#WRT_TEST_ADD_INTERNAL_DEPENDENCIES(${TARGET_NAME} ${TARGET_DPL_UTILS_EFL}) +WRT_TEST_BUILD(${TARGET_NAME} ${DPL_TESTS_UTIL_SOURCES}) +WRT_TEST_INSTALL(${TARGET_NAME}) diff --git a/tests/utils/bash_utils.cpp b/tests/utils/bash_utils.cpp new file mode 100644 index 0000000..7dac1fc --- /dev/null +++ b/tests/utils/bash_utils.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file bash_utils.cpp + * @author Iwanek Tomasz + * @version 1.0 + */ +#include +#include +#include + +using namespace BashUtils; + +RUNNER_TEST_GROUP_INIT(DPL_BASH_UTILS) + +/* +Name: Bash_Utils_escape_arg +Description:tests ecaping bash special characters for command arguments +Expected: matching string +*/ +RUNNER_TEST(Bash_Utils_escape_arg) +{ + RUNNER_ASSERT_MSG(escape_arg(std::string( + "valid")) == "\"valid\"", + "Valid argument failed"); + LogDebug("\"val\\!d\"" << " " << escape_arg(std::string("val!d"))); + RUNNER_ASSERT_MSG(escape_arg(std::string( + "val!d")) == "\"val\\!d\"", + "Single escaped character in argument failed"); + LogDebug("\"v\\$l\\$\\$\"" << " " << escape_arg(std::string("v$l$$"))); + RUNNER_ASSERT_MSG(escape_arg(std::string( + "v$l$$")) == "\"v\\$l\\$\\$\"", + "Multiple occurences of single special character in argument failed"); + LogDebug("\"v\\`\\$\\\"\\!d\\`\"" << " " << + escape_arg(std::string("v`$\"!d`"))); + RUNNER_ASSERT_MSG(escape_arg(std::string( + "v`$\"!d`")) == "\"v\\`\\$\\\"\\!d\\`\"", + "Multiple occurences of multiple special character in argument failed"); +} diff --git a/tests/utils/main.cpp b/tests/utils/main.cpp new file mode 100644 index 0000000..42ffe3a --- /dev/null +++ b/tests/utils/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file main.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of main + */ +#include + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} + diff --git a/tests/utils/path_tests.cpp b/tests/utils/path_tests.cpp new file mode 100644 index 0000000..e612ad7 --- /dev/null +++ b/tests/utils/path_tests.cpp @@ -0,0 +1,958 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file path.h + * @author Tomasz Iwanek (t.iwanek@samsung.com) + * @version 1.0 + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace DPL::Utils; + +namespace { +//do not used path here we test it +std::string rootTest = "/tmp/wrttest/"; +} + +#define ROOTGUARD_TESTMETHOD(FUNC) \ +{ \ + bool catched = false; \ + Try { \ + FUNC; \ + } Catch(Path::RootDirectoryError) { \ + catched = true; \ + } \ + RUNNER_ASSERT_MSG(catched, "Use of method should be protected against root diretory"); \ +} \ + +RUNNER_TEST_GROUP_INIT(DPL_Path) + +/* +Name: path_touch +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_mkfile) +{ + DPL::ScopedDir sd(rootTest); + + struct stat st; + memset(&st, 0, sizeof(struct stat)); + Path path = Path(rootTest) / "touch.txt"; + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "File should not be created"); + RUNNER_ASSERT(!path.Exists()); + MakeEmptyFile(path); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "File should be created"); + RUNNER_ASSERT(path.Exists()); + RUNNER_ASSERT(path.IsFile()); + RUNNER_ASSERT(!path.IsDir()); + RUNNER_ASSERT(!path.IsSymlink()); +} + +/* +Name: path_touch +Description: tries to craete file when it exists +Expected: failure +*/ +RUNNER_TEST(path_mkfile_exists) +{ + DPL::ScopedDir sd(rootTest); + + Path path = Path(rootTest) / "touch.txt"; + MakeEmptyFile(path); + RUNNER_ASSERT(path.Exists()); + bool cannotCreate2ndTime = false; + Try + { + MakeEmptyFile(path); + } + Catch(Path::AlreadyExists) + { + cannotCreate2ndTime = true; + } + RUNNER_ASSERT_MSG(cannotCreate2ndTime, "File created should not be able to be created second time"); +} + +/* +Name: path_exists_and_is_file_or_dir +Description: test for checking for existence of directory or file +Expected: success +*/ +RUNNER_TEST(path_exists_and_is_file_or_dir) +{ + DPL::ScopedDir sd(rootTest); + + Path file = Path(rootTest) / "testfile.txt"; + MakeEmptyFile(file); + RUNNER_ASSERT_MSG(file.ExistsAndIsFile(), "File should exist"); + RUNNER_ASSERT_MSG(!file.ExistsAndIsDir(), "It should not be a directory"); + + Path dir = Path(rootTest) / "testdir"; + MakeDir(dir); + RUNNER_ASSERT_MSG(dir.ExistsAndIsDir(), "Directory should exist"); + RUNNER_ASSERT_MSG(!dir.ExistsAndIsFile(), "Is should not be a file"); +} + +/* +Name: path_mkfile_invalid_path +Description: tries to create file in not exisitng directory +Expected: failure at creation +*/ +RUNNER_TEST(path_mkfile_invalid_path) +{ + DPL::ScopedDir sd(rootTest); + + Path path = Path(rootTest) / "not_existing" / "touch.txt"; + bool cannotCreate = false; + Try + { + MakeEmptyFile(path); + } + Catch(Path::OperationFailed) + { + cannotCreate = true; + } + RUNNER_ASSERT_MSG(cannotCreate, "File created should not be able to be created"); +} + +/* +Name: path_mkdir +Description: creates valid directory +Expected: success direcotry creation +*/ +RUNNER_TEST(path_mkdir) +{ + DPL::ScopedDir sd(rootTest); + + struct stat st; + memset(&st, 0, sizeof(struct stat)); + Path path = Path(rootTest) / "touchDir"; + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "Directory should not be created"); + RUNNER_ASSERT(!path.Exists()); + MakeDir(path); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "Directory should be created"); + RUNNER_ASSERT(path.Exists()); + RUNNER_ASSERT(!path.IsFile()); + RUNNER_ASSERT(path.IsDir()); + RUNNER_ASSERT(!path.IsSymlink()); +} + +/* +Name: path_symlink +Description: chekc if symlink is correctly recognized +Expected: method isSymlink returns true +*/ +RUNNER_TEST(path_symlink) +{ + DPL::ScopedDir sd(rootTest); + + struct stat st; + memset(&st, 0, sizeof(struct stat)); + Path path = Path(rootTest) / "symlink"; + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "Symlink should not be created"); + RUNNER_ASSERT(!path.Exists()); + (void)symlink("/nonexistisfile/file/file/file ", path.Fullpath().c_str()); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "Symlink should be created"); + RUNNER_ASSERT(path.Exists()); + RUNNER_ASSERT(!path.IsFile()); + RUNNER_ASSERT(!path.IsDir()); + RUNNER_ASSERT(path.IsSymlink()); +} + +/* +Name: path_construction_empty +Description: tries to construct empty path +Expected: failure +*/ +RUNNER_TEST(path_construction_empty) +{ + bool passed = false; + Try + { + Path path1(std::string("")); + } + Catch(Path::EmptyPath) + { + passed = true; + } + RUNNER_ASSERT_MSG(passed, "Construction with empty path do not fails"); +} + +/* +Name: path_construction_root +Description: tries to construct root path +Expected: success +*/ +RUNNER_TEST(path_construction_root) +{ + Path path1(std::string("/")); + RUNNER_ASSERT(path1.Fullpath() == "/"); + RUNNER_ASSERT(path1.Filename() == ""); + bool passed = false; + Try + { + RUNNER_ASSERT(path1.DirectoryName() == "/"); + } + Catch(Path::InternalError) + { + passed = true; + } + RUNNER_ASSERT_MSG(passed, "Directory name for root should be an error"); +} + +/* +Name: path_construction_1 +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_construction_1) +{ + DPL::ScopedFree sf(getcwd(NULL, 0)); + + Path path1(std::string("/test/bin/file")); + RUNNER_ASSERT(path1.Fullpath() == "/test/bin/file"); + RUNNER_ASSERT(path1.Filename() == "file"); + RUNNER_ASSERT(path1.DirectoryName() == "/test/bin"); +} + +/* +Name: path_construction_2 +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_construction_2) +{ + DPL::ScopedFree sf(getcwd(NULL, 0)); + std::string cwd(sf.Get()); + + if("/" == cwd) + cwd = ""; + + Path path2(std::string("test/bin/file.eas")); + RUNNER_ASSERT(path2.Fullpath() == cwd + "/test/bin/file.eas"); + RUNNER_ASSERT(path2.Filename() == "file.eas"); + RUNNER_ASSERT(path2.DirectoryName() == cwd + "/test/bin"); +} + +/* +Name: path_construction_3 +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_construction_3) +{ + DPL::ScopedFree sf(getcwd(NULL, 0)); + std::string cwd(sf.Get()); + + if("/" == cwd) + cwd = ""; + + Path path3("test/23/abc"); + RUNNER_ASSERT(path3.Fullpath() == cwd + "/test/23/abc"); + RUNNER_ASSERT(path3.Filename() == "abc"); + RUNNER_ASSERT(path3.DirectoryName() == cwd + "/test/23"); +} + +/* +Name: path_construction_4 +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_construction_4) +{ + DPL::ScopedFree sf(getcwd(NULL, 0)); + + Path path4("/test/bin/abc"); + RUNNER_ASSERT(path4.Fullpath() == "/test/bin/abc"); + RUNNER_ASSERT(path4.Filename() == "abc"); + RUNNER_ASSERT(path4.DirectoryName() == "/test/bin"); +} + +/* +Name: path_construction_5 +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_construction_5) +{ + DPL::ScopedFree sf(getcwd(NULL, 0)); + std::string cwd(sf.Get()); + + if("/" == cwd) + cwd = ""; + + Path path5(DPL::String(L"test/bin/file.st.exe")); + RUNNER_ASSERT(path5.Fullpath() == cwd + "/test/bin/file.st.exe"); + RUNNER_ASSERT(path5.Filename() == "file.st.exe"); + RUNNER_ASSERT(path5.DirectoryName() == cwd + "/test/bin"); +} + +/* +Name: path_construction_6 +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_construction_6) +{ + DPL::ScopedFree sf(getcwd(NULL, 0)); + + Path path6(DPL::String(L"/test/bin/file")); + RUNNER_ASSERT(path6.Fullpath() == "/test/bin/file"); + RUNNER_ASSERT(path6.Filename() == "file"); + RUNNER_ASSERT(path6.DirectoryName() == "/test/bin"); +} + +/* +Name: path_construction_7 +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_construction_7) +{ + DPL::ScopedFree sf(getcwd(NULL, 0)); + std::string cwd(sf.Get()); + + if("/" == cwd) + cwd = ""; + + Path path7 = Path("test") / "a///23/lol"; + RUNNER_ASSERT(path7.Fullpath() == cwd + "/test/a/23/lol"); + RUNNER_ASSERT(path7.Filename() == "lol"); + RUNNER_ASSERT(path7.DirectoryName() == cwd + "/test/a/23"); +} + +/* +Name: path_construction_8 +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_construction_8) +{ + DPL::ScopedFree sf(getcwd(NULL, 0)); + + Path path8 = Path("/test/bin/") / "123" / "dir1.dll"; + RUNNER_ASSERT(path8.Fullpath() == "/test/bin/123/dir1.dll"); + RUNNER_ASSERT(path8.Filename() == "dir1.dll"); + RUNNER_ASSERT(path8.DirectoryName() == "/test/bin/123"); +} + +/* +Name: path_construction_9 +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_construction_9) +{ + DPL::ScopedFree sf(getcwd(NULL, 0)); + + Path path9 = Path("/test/bin/file.txt//"); + RUNNER_ASSERT(path9.Fullpath() == "/test/bin/file.txt"); + RUNNER_ASSERT(path9.Filename() == "file.txt"); + RUNNER_ASSERT(path9.DirectoryName() == "/test/bin"); +} + +/* +Name: path_construction_10 +Description: constructs paths by appending +Expected: success full constrution +*/ +RUNNER_TEST(path_construction_10) +{ + Path path10 = Path("/test/"); + path10 /= "one"; + path10 /= std::string("two"); + path10 /= DPL::String(L"three"); + RUNNER_ASSERT(path10.Fullpath() == "/test/one/two/three"); + RUNNER_ASSERT(path10.Filename() == "three"); + RUNNER_ASSERT(path10.DirectoryName() == "/test/one/two"); +} + +/* +Name: path_remove +Description: tests removing paths +Expected: successfull path remove +*/ +RUNNER_TEST(path_remove_valid) +{ + DPL::ScopedDir sd(rootTest); + + struct stat st; + memset(&st, 0, sizeof(struct stat)); + Path path = Path(rootTest) / "touchDir"; + RUNNER_ASSERT(!path.Exists()); + + MakeDir(path); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "Directory should be created"); + RUNNER_ASSERT(path.Exists()); + + Remove(path); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "Directory should not be created"); + RUNNER_ASSERT(!path.Exists()); + + MakeEmptyFile(path); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "File should be created"); + RUNNER_ASSERT(path.Exists()); + + Remove(path); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "File should not be created"); + RUNNER_ASSERT(!path.Exists()); +} + +/* +Name: path_try_remove +Description: tests removing paths +Expected: successfull path remove once +*/ +RUNNER_TEST(path_try_remove_valid) +{ + DPL::ScopedDir sd(rootTest); + + struct stat st; + memset(&st, 0, sizeof(struct stat)); + Path path = Path(rootTest) / "touchDir"; + RUNNER_ASSERT(!path.Exists()); + + MakeDir(path); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "Directory should be created"); + RUNNER_ASSERT(path.Exists()); + + RUNNER_ASSERT(TryRemove(path)); + RUNNER_ASSERT(!TryRemove(path)); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "Directory should not be created"); + RUNNER_ASSERT(!path.Exists()); + + MakeEmptyFile(path); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "File should be created"); + RUNNER_ASSERT(path.Exists()); + + RUNNER_ASSERT(TryRemove(path)); + RUNNER_ASSERT(!TryRemove(path)); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "File should not be created"); + RUNNER_ASSERT(!path.Exists()); +} + +/* +Name: path_remove_invalid +Description: tests removing invalid paths +Expected: failure at path remove +*/ +RUNNER_TEST(path_remove_invalid) +{ + DPL::ScopedDir sd(rootTest); + + Path path = Path(rootTest) / "touchDir"; + + bool removedNotExisting = true; + Try + { + Remove(path); + } + Catch(Path::OperationFailed) + { + removedNotExisting = false; + } + RUNNER_ASSERT_MSG(!removedNotExisting, "Removing not existing file"); +} + +/* +Name: path_rename +Description: tests path renaming +Expected: path is successfully renamed +*/ +RUNNER_TEST(path_rename) +{ + DPL::ScopedDir sd(rootTest); + + struct stat st; + memset(&st, 0, sizeof(struct stat)); + Path path = Path(rootTest) / "touchDir"; + Path dirpath = Path(rootTest) / "directory"; + Path path2 = dirpath / "touchDir2"; + + MakeDir(dirpath); + + MakeEmptyFile(path); + RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "File should be created"); + RUNNER_ASSERT(path.Exists()); + RUNNER_ASSERT(!path2.Exists()); + + Rename(path, path2); + RUNNER_ASSERT(!path.Exists()); + RUNNER_ASSERT(path2.Exists()); + + Rename(path2, path); + RUNNER_ASSERT(path.Exists()); + RUNNER_ASSERT(!path2.Exists()); +} + +/* +Name: path_rename_xdev +Description: tests path renaming between devices +Expected: path is successfully renamed +*/ +RUNNER_TEST(path_rename_xdev) +{ + //assuming /opt/usr and /usr is normally on other partitions on device + //TODO: better + Path path = Path("/opt/usr") / "touchDir"; + Path dirpath = path / "directory"; + Path filepath = path / "file.txt"; + + Path path2 = Path("/usr") / "touchDir2"; + Path dirpath2 = path2 / "directory"; + Path filepath2 = path2 / "file.txt"; + + TryRemove(path); + + MakeDir(path); + MakeDir(dirpath); + MakeEmptyFile(filepath); + + RUNNER_ASSERT(path.Exists()); + RUNNER_ASSERT(dirpath.Exists()); + RUNNER_ASSERT(filepath.Exists()); + RUNNER_ASSERT(!path2.Exists()); + RUNNER_ASSERT(!dirpath2.Exists()); + RUNNER_ASSERT(!filepath2.Exists()); + + Rename(path, path2); + RUNNER_ASSERT(!path.Exists()); + RUNNER_ASSERT(!dirpath.Exists()); + RUNNER_ASSERT(!filepath.Exists()); + RUNNER_ASSERT(path2.Exists()); + RUNNER_ASSERT(dirpath2.Exists()); + RUNNER_ASSERT(filepath2.Exists()); + + Rename(path2, path); + RUNNER_ASSERT(path.Exists()); + RUNNER_ASSERT(dirpath.Exists()); + RUNNER_ASSERT(filepath.Exists()); + RUNNER_ASSERT(!path2.Exists()); + RUNNER_ASSERT(!dirpath2.Exists()); + RUNNER_ASSERT(!filepath2.Exists()); + + Remove(path); +} + +/** + * Name: path_basename + * Description: check basename equivalents + * Expected: failure + */ +RUNNER_TEST(path_basename) +{ + DPL::ScopedDir sd(rootTest); + Path path = Path(rootTest) / "directory" / "touch.txt"; + RUNNER_ASSERT(path.DirectoryName() == path.DirectoryPath().Fullpath()); + RUNNER_ASSERT(path.DirectoryPath().DirectoryName() == path.DirectoryPath().DirectoryPath().Fullpath()); +} + +/** + * Name: path_safe + * Description: check if operations cannot be executed on root directory + * + * This is check because of default path is root and it should not be used usually + * Default constructor is unfortnatelly easier to use + * + * Expected: failure + */ +RUNNER_TEST(path_safe) +{ + DPL::ScopedDir sd(rootTest); + Path normal = Path(rootTest) / "directory" / "touch.txt"; + Path root("/"); + ROOTGUARD_TESTMETHOD( Rename(normal, root) ); + ROOTGUARD_TESTMETHOD( Rename(root, root) ); + ROOTGUARD_TESTMETHOD( Rename(root, normal) ); + ROOTGUARD_TESTMETHOD( CopyDir(normal, root) ); + ROOTGUARD_TESTMETHOD( CopyDir(root, root) ); + ROOTGUARD_TESTMETHOD( CopyDir(root, normal) ); + ROOTGUARD_TESTMETHOD( CopyFile(normal, root) ); + ROOTGUARD_TESTMETHOD( CopyFile(root, root) ); + ROOTGUARD_TESTMETHOD( CopyFile(root, normal) ); + ROOTGUARD_TESTMETHOD( Remove(root) ); + ROOTGUARD_TESTMETHOD( MakeEmptyFile(root) ); + ROOTGUARD_TESTMETHOD( MakeDir(root) ); +} + +/** + * Name: path_size + * Description: check testing size of file + * Expected: correct size + */ +RUNNER_TEST(path_size) +{ + DPL::ScopedDir sd(rootTest); + Path path = Path(rootTest) / "touch.txt"; + DPL::Utils::MakeEmptyFile(path); + RUNNER_ASSERT(path.Size() == 0); + + { + DPL::FileOutput out(path.Fullpath()); + DPL::BinaryQueue bq; + bq.AppendCopy("123456789", 9); + out.Write(bq, bq.Size()); + out.Close(); + RUNNER_ASSERT(path.Size() == 9); + } + + { + DPL::FileOutput out(path.Fullpath()); + DPL::BinaryQueue bq; + bq.AppendCopy("123456789", 4); + out.Write(bq, bq.Size()); + out.Close(); + RUNNER_ASSERT(path.Size() == 4); + } +} + +/** +Name: path_copy +Description: tests path coping directory andfiles +Expected: coping should be done +*/ +RUNNER_TEST(path_copy_directory) +{ + DPL::ScopedDir sd(rootTest); + + Path path = Path(rootTest) / "sourceDir"; + Path innerPath = Path(rootTest) / "sourceDir" / "level1" ; + Path innerPath2 = Path(rootTest) / "sourceDir" / "level1" / "level2"; + Path file1 = Path(rootTest) / "sourceDir" / "level1" / "level2" / "file1.txt"; + Path file2 = Path(rootTest) / "sourceDir" / "level1" / "level2" / "file2.txt"; + Path file3 = Path(rootTest) / "sourceDir" / "level1" / "file3.txt"; + Path file4 = Path(rootTest) / "sourceDir" / "file4.txt"; + + Path tfile1 = Path(rootTest) / "targetDir" / "level1" / "level2" / "file1.txt"; + Path tfile2 = Path(rootTest) / "targetDir" / "level1" / "level2" / "file2.txt"; + Path tfile3 = Path(rootTest) / "targetDir" / "level1" / "file3.txt"; + Path tfile4 = Path(rootTest) / "targetDir" / "file4.txt"; + + Path target = Path(rootTest) / "targetDir"; + + DPL::Utils::MakeDir(path); + DPL::Utils::MakeDir(innerPath); + DPL::Utils::MakeDir(innerPath2); + DPL::Utils::MakeEmptyFile(file1); + DPL::Utils::MakeEmptyFile(file2); + DPL::Utils::MakeEmptyFile(file3); + DPL::Utils::MakeEmptyFile(file4); + + DPL::Utils::CopyDir(path, target); + + RUNNER_ASSERT_MSG(tfile1.Exists(), tfile1.Fullpath() + " not exists"); + RUNNER_ASSERT_MSG(tfile1.IsFile(), tfile1.Fullpath() + " is not file"); + RUNNER_ASSERT_MSG(tfile2.Exists(), tfile2.Fullpath() + " not exists"); + RUNNER_ASSERT_MSG(tfile2.IsFile(), tfile2.Fullpath() + " is not file"); + RUNNER_ASSERT_MSG(tfile3.Exists(), tfile3.Fullpath() + " not exists"); + RUNNER_ASSERT_MSG(tfile3.IsFile(), tfile3.Fullpath() + " is not file"); + RUNNER_ASSERT_MSG(tfile4.Exists(), tfile4.Fullpath() + " not exists"); + RUNNER_ASSERT_MSG(tfile4.IsFile(), tfile4.Fullpath() + " is not file"); +} + +/* +Name: path_copy_inner +Description: tests path coping to subdirectory +Expected: coping shoudl fail +*/ +RUNNER_TEST(path_copy_inner) +{ + DPL::ScopedDir sd(rootTest); + + Path path = Path(rootTest) / "touchDir"; + Path inner = Path(rootTest) / "touchDir" / "innerDirectory"; + + bool exceptionCatched = false; + Try + { + DPL::Utils::CopyDir(path, inner); + } + Catch(DPL::Utils::Path::CannotCopy) + { + exceptionCatched = true; + } + RUNNER_ASSERT_MSG(exceptionCatched, "Copy should fail"); +} + +/* +Name: issubpath +Description: tests method compare if one path is subpath of another +Expected: correct results +*/ +RUNNER_TEST(path_issubpath) +{ + Path path1 = Path(rootTest) / "touchDir/asd/sdf"; + Path path2 = Path(rootTest) / "touchDir/asd/sdf/123"; + Path path3 = Path(rootTest) / "touchDir/asd/sdno"; + Path path4 = Path("/"); + + RUNNER_ASSERT(path1.isSubPath(path2)); + RUNNER_ASSERT(!path1.isSubPath(path3)); + RUNNER_ASSERT(!path1.isSubPath(path4)); + + RUNNER_ASSERT(!path2.isSubPath(path1)); + RUNNER_ASSERT(!path2.isSubPath(path3)); + RUNNER_ASSERT(!path2.isSubPath(path4)); + + RUNNER_ASSERT(path4.isSubPath(path1)); + RUNNER_ASSERT(path4.isSubPath(path2)); + RUNNER_ASSERT(path4.isSubPath(path3)); +} + +/* +Name: path_rename_same +Description: tests if renam does not brokens file if target location is equal to source location +Expected: path is avaliable +*/ +RUNNER_TEST(path_rename_same) +{ + DPL::ScopedDir sd(rootTest); + + struct stat st; + memset(&st, 0, sizeof(struct stat)); + Path path = Path(rootTest) / "touchDir"; + + MakeDir(path); + Rename(path, path); + RUNNER_ASSERT(path.Exists()); +} + +/* +Name: path_iterate_not_directory +Description: iterates not a directory +Expected: success full constrution +*/ +RUNNER_TEST(path_iterate_not_directory) +{ + DPL::ScopedDir sd(rootTest); + + Path fileTest = Path(rootTest) / "file.txt"; + MakeEmptyFile(fileTest); + + bool passed = false; + Try + { + FOREACH(file, fileTest) + { + + } + } + Catch(Path::NotDirectory) + { + passed = true; + } + RUNNER_ASSERT(passed); +} + +/* +Name: path_construction +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_iterate_empty_directory) +{ + DPL::ScopedDir sd(rootTest); + + Path dirTest = Path(rootTest) / "directory"; + MakeDir(dirTest); + + bool passed = true; + Try + { + FOREACH(file, dirTest) + { + passed = false; + LogError("Directory should be empty"); + } + } + Catch(Path::NotDirectory) + { + passed = false; + LogError("Directory should exists"); + } + RUNNER_ASSERT(passed); +} + +/* +Name: path_construction +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_iterate_notempty_directory) +{ + DPL::ScopedDir sd(rootTest); + + Path dirTest = Path(rootTest) / "directory"; + + Path path1 = Path(rootTest) / "directory" / "file1"; + Path path2 = Path(rootTest) / "directory" / "file2"; + Path path3 = Path(rootTest) / "directory" / "file3"; + + std::set resultSet; + std::set testSet; + testSet.insert(path1.Fullpath()); + testSet.insert(path2.Fullpath()); + testSet.insert(path3.Fullpath()); + + MakeDir(dirTest); + MakeEmptyFile(path1); + MakeEmptyFile(path2); + MakeEmptyFile(path3); + + FOREACH(file, dirTest) + { + resultSet.insert(file->Fullpath()); + } + + RUNNER_ASSERT_MSG(testSet == resultSet, "Testing"); +} + +/* +Name: path_construction +Description: constructs paths in many ways +Expected: success full constrution +*/ +RUNNER_TEST(path_iterator_copy_constructor) +{ + DPL::ScopedDir sd(rootTest); + + Path dirTest = Path(rootTest) / "directory"; + + Path path1 = Path(rootTest) / "directory" / "file1"; + Path path2 = Path(rootTest) / "directory" / "file2"; + Path path3 = Path(rootTest) / "directory" / "file3"; + + MakeDir(dirTest); + MakeEmptyFile(path1); + MakeEmptyFile(path2); + MakeEmptyFile(path3); + + std::shared_ptr iter1(new Path::Iterator((Path(rootTest) / "directory").Fullpath().c_str())); + + //as it's input iterator it's guaranteed for one element to be iterate only once + (*iter1)++; + std::shared_ptr iter2(new Path::Iterator( (*iter1))); + iter1.reset(); + (*iter2)++; + ++(*iter2); + RUNNER_ASSERT_MSG(*iter2 == dirTest.end(), "Iterator is in broken state"); + iter2.reset(); +} + +/* +Name: path_extension_test +Description: Tests if file extension is correct +Expected: Proper recognition of extensions +*/ +RUNNER_TEST(path_extension_test) +{ + Path path1("/path/to/file.dot"); + Path path2("/path/to/file..dot"); + Path path3("/path/to/file..dot."); + Path path4("/path/to/file..dot.dot"); + Path path5("/path/to.dot/file"); + Path path6("./path/to/file"); + Path path7("./path/to/file"); + Path path8("/path/../file.xml"); + Path path9("/path/../file.XML"); + Path path10("/path/../file.myfileextension"); + + RUNNER_ASSERT(path1.Extension() == "dot"); + RUNNER_ASSERT(path2.Extension() == "dot"); + RUNNER_ASSERT(path3.Extension() == ""); + RUNNER_ASSERT(path4.Extension() == "dot"); + RUNNER_ASSERT(path5.Extension() == ""); + RUNNER_ASSERT(path6.Extension() == ""); + RUNNER_ASSERT(path7.Extension() == ""); + RUNNER_ASSERT(path8.Extension() == "xml"); + RUNNER_ASSERT(path9.Extension() != "xml"); + RUNNER_ASSERT(path10.Extension() == "myfileextension"); +} + +/* +Name: path_has_extension_test +Description: Tests if file extension is correct +Expected: Proper recognition of extensions +*/ +RUNNER_TEST(path_has_extension_test) +{ + + Path dirTest = Path("extension"); + + Path path1 = dirTest / "file1.XML"; + Path path2 = dirTest / "file2.JPG"; + Path path3 = dirTest / "file3."; + Path path4 = dirTest / "file4"; + Path path5 = dirTest / "file5.HTML"; + Path path6 = dirTest / "file6.JS"; + Path path7 = dirTest / "file7.VERY_VERY_LONG_EXTENSION"; + Path path8 = dirTest / "file8.VERY.VERY.LONG.EXTENSION.WITH.DOTS"; + + RUNNER_ASSERT_MSG(path1.hasExtension("XML"), "Problem with comparison"); + RUNNER_ASSERT_MSG(path2.hasExtension("JPG"), "Problem with comparison"); + RUNNER_ASSERT_MSG(path5.hasExtension("HTML"), "Problem with comparison"); + RUNNER_ASSERT_MSG(path6.hasExtension("JS"), "Problem with comparison"); + RUNNER_ASSERT_MSG(path7.hasExtension("VERY_VERY_LONG_EXTENSION"), + "Problem with comparison"); + RUNNER_ASSERT_MSG(path8.hasExtension("DOTS"), "Problem with comparison"); + + RUNNER_ASSERT_MSG(!path1.hasExtension(".XML"), + "Wrong argument in hasExtension() function"); + RUNNER_ASSERT_MSG(!path1.hasExtension("MXL"), + "Wrong argument in hasExtension() function"); + RUNNER_ASSERT_MSG(!path2.hasExtension(".JPG"), + "Wrong argument in hasExtension() function"); + RUNNER_ASSERT_MSG(!path5.hasExtension(".HTML"), + "Wrong argument in hasExtension() function"); + RUNNER_ASSERT_MSG(!path6.hasExtension(".JS"), + "Wrong argument in hasExtension() function"); + + RUNNER_ASSERT_MSG(path3.hasExtension(""), "Extension length is 0"); + + RUNNER_ASSERT_MSG(path4.hasExtension(""), "Extension length is 0"); +} + +/* +Name: path_create_temp_dir +Description: tests if temp dir was created +Expected: temp dir exists +*/ +RUNNER_TEST(path_create_temp_dir) +{ + Path p1 = CreateTempPath(Path("/usr/tmp/")); + Path p2 = CreateTempPath(Path("/opt/usr/apps/tmp/")); + Path p3 = CreateTempPath(Path("/opt/usr/apps/tmp/")); + + RUNNER_ASSERT_MSG(p1.Exists(), "Temp dir doesn't exists"); + RUNNER_ASSERT_MSG(p2.Exists(), "Temp dir doesn't exists"); + RUNNER_ASSERT_MSG(p3.Exists(), "Temp dir doesn't exists"); + RUNNER_ASSERT_MSG(p2.Fullpath() != p3.Fullpath(), "Each temp path should be unique due to having tv_usec in dir name."); +} diff --git a/tests/utils/widget_version.cpp b/tests/utils/widget_version.cpp new file mode 100644 index 0000000..5d2bc71 --- /dev/null +++ b/tests/utils/widget_version.cpp @@ -0,0 +1,641 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file widget_version.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for test cases for engine internal tests + */ +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL_WIDGET_VERSION) + +/* +Name: WidgetVersion_M2_O0 +Description: tests correct parsing of version widget in format: [major].[minor] +Expected: major and minor parts matches expected values +*/ +RUNNER_TEST(WidgetVersion_M2_O0) +{ + DPL::String raw(L"1.2"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == true); + RUNNER_ASSERT(version.Major() == DPL::String(L"1")); + RUNNER_ASSERT(version.Minor() == DPL::String(L"2")); + RUNNER_ASSERT(version.Micro() == DPL::Optional()); + RUNNER_ASSERT(version.Optional() == DPL::Optional()); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M2_O0_nonwac_1 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M2_O0_nonwac_1) +{ + DPL::String raw(L"a1.2"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M2_O0_nonwac_2 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M2_O0_nonwac_2) +{ + DPL::String raw(L"1.2a"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M2_O0_nonwac_3 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M2_O0_nonwac_3) +{ + DPL::String raw(L"aaa1.2bbb"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M2_O0_nonwac_4 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M2_O0_nonwac_4) +{ + DPL::String raw(L"1a.a2"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M2_O0_long +Description: tests correct parsing of version widget in format: [major].[minor] + for huge number +Expected: major and minor parts matches expected values +*/ +RUNNER_TEST(WidgetVersion_M2_O0_long) +{ + DPL::String raw( + L"123456789012345678901234567890.98765432109876543210987654321"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == true); + RUNNER_ASSERT(version.Major() == + DPL::String(L"123456789012345678901234567890")); + RUNNER_ASSERT(version.Minor() == + DPL::String(L"98765432109876543210987654321")); + RUNNER_ASSERT(version.Micro() == DPL::Optional()); + RUNNER_ASSERT(version.Optional() == DPL::Optional()); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M3_O0 +Description: tests correct wac version number +Expected: major and minor and micro parts matches expected values. + Version should be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M3_O0) +{ + DPL::String raw(L"1.2.3"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == true); + RUNNER_ASSERT(version.Major() == DPL::String(L"1")); + RUNNER_ASSERT(version.Minor() == DPL::String(L"2")); + RUNNER_ASSERT(version.Micro() == DPL::Optional(L"3")); + RUNNER_ASSERT(version.Optional() == DPL::Optional()); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M3_O0_nonwac_1 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M3_O0_nonwac_1) +{ + DPL::String raw(L"a1a.2.3"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M3_O0_nonwac_2 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M3_O0_nonwac_2) +{ + DPL::String raw(L"1.b2.3"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M3_O0_nonwac_3 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M3_O0_nonwac_3) +{ + DPL::String raw(L"1.2.3c"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M3_O1_1 +Description: tests correct wac version number with optional part +Expected: major and minor and micro and optional parts matches expected values. + Version should be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M3_O1_1) +{ + DPL::String raw(L"1.2.3 test111"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == true); + RUNNER_ASSERT(version.Major() == DPL::String(L"1")); + RUNNER_ASSERT(version.Minor() == DPL::String(L"2")); + RUNNER_ASSERT(version.Micro() == DPL::Optional(L"3")); + RUNNER_ASSERT(version.Optional() == DPL::Optional(L"test111")); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M3_O1_1 +Description: tests correct wac version number with numeric optional part +Expected: major and minor and micro and optional parts matches expected values. + Version should be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M3_O1_2) +{ + DPL::String raw(L"1.2.3 111"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == true); + RUNNER_ASSERT(version.Major() == DPL::String(L"1")); + RUNNER_ASSERT(version.Minor() == DPL::String(L"2")); + RUNNER_ASSERT(version.Micro() == DPL::Optional(L"3")); + RUNNER_ASSERT(version.Optional() == DPL::Optional(L"111")); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M3_O1_3 +Description: tests if version is recognized as wac version number + when trailer spaces exists +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M3_O1_3) +{ + DPL::String raw(L"1.2.3 "); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M2_O1_1 +Description: tests if version is recognized as wac version number + when optional part +Expected: version should be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_M2_O1_1) +{ + DPL::String raw(L"1.2 t"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == true); + RUNNER_ASSERT(version.Major() == DPL::String(L"1")); + RUNNER_ASSERT(version.Minor() == DPL::String(L"2")); + RUNNER_ASSERT(version.Micro() == DPL::Optional()); + RUNNER_ASSERT(version.Optional() == DPL::Optional(L"t")); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M2_O1_2 +Description: tests if version is recognized as wac version number + with numeric optional part. +Expected: major and minor and optional parts matches expected values. + Version should be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_M2_O1_2) +{ + DPL::String raw(L"1.2 1234"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == true); + RUNNER_ASSERT(version.Major() == DPL::String(L"1")); + RUNNER_ASSERT(version.Minor() == DPL::String(L"2")); + RUNNER_ASSERT(version.Micro() == DPL::Optional()); + RUNNER_ASSERT(version.Optional() == DPL::Optional(L"1234")); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M4_O0_1 +Description: Tests if version is recognized as wac version number. +Expected: major and minor and micro and optional parts matches expected values. + Version should be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_M4_O0_1) +{ + DPL::String raw(L"1.1"); + DPL::String majorV(L"1"); + DPL::String minorV(L"1"); + DPL::Optional microV = DPL::Optional(); + DPL::Optional optionalV = DPL::Optional(); + WidgetVersion version(majorV, minorV, microV, optionalV); + + RUNNER_ASSERT(version.IsWac() == true); + RUNNER_ASSERT(version.Major() == majorV); + RUNNER_ASSERT(version.Minor() == minorV); + RUNNER_ASSERT(version.Micro() == microV); + RUNNER_ASSERT(version.Optional() == optionalV); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M4_O0_nonwac_1 +Description: Tests if version is recognized as wac version number. +Expected: Version should be recognized as non wac compatible. +*/ +RUNNER_TEST(WidgetVersion_M4_O0_nonwac_1) +{ + DPL::String raw(L"a1.1"); + WidgetVersion version(L"a1", L"1", DPL::Optional(), DPL::Optional()); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M4_O0_nonwac_2 +Description: Tests if version is recognized as wac version number. +Expected: Version should not be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_M4_O0_nonwac_2) +{ + DPL::String raw(L"1.1a"); + WidgetVersion version(L"1", L"1a", DPL::Optional(), DPL::Optional()); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M4_O1_1 +Description: Tests if version is recognized as wac version number. +Expected: major, minor, micro and optional parts matches expected values. + Version should be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_M4_O1_1) +{ + DPL::String raw(L"1.1.1"); + DPL::String majorV(L"1"); + DPL::String minorV(L"1"); + DPL::Optional microV = DPL::Optional(L"1"); + DPL::Optional optionalV = DPL::Optional(); + WidgetVersion version(majorV, minorV, microV, optionalV); + + RUNNER_ASSERT(version.IsWac() == true); + RUNNER_ASSERT(version.Major() == majorV); + RUNNER_ASSERT(version.Minor() == minorV); + RUNNER_ASSERT(version.Micro() == microV); + RUNNER_ASSERT(version.Optional() == optionalV); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M4_O1_nonwac_1 +Description: Tests if version is recognized as wac version number. +Expected: Version should not be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_M4_O1_nonwac_1) +{ + DPL::String majorV(L"1"); + DPL::String minorV(L"1"); + WidgetVersion version(L"1", L"1", DPL::Optional(L"1a"), DPL::Optional()); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == L"1.1.1a"); +} + +/* +Name: WidgetVersion_M4_O1_nonwac_1 +Description: Tests if version is recognized as wac version number. +Expected: Version should not be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_M4_O1_nonwac_2) +{ + WidgetVersion version(L"1", L"1", DPL::Optional(L"a1"), DPL::Optional()); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == L"1.1.a1"); +} + +/* +Name: WidgetVersion_M4_O2_1 +Description: Tests if version is recognized as wac version number. +Expected: major, minor, micro and optional parts matches expected values. + Version should be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_M4_O2_1) +{ + DPL::String raw(L"1.1.1 a1"); + DPL::String majorV(L"1"); + DPL::String minorV(L"1"); + DPL::Optional microV = DPL::Optional(L"1"); + DPL::Optional optionalV = DPL::Optional(L"a1"); + WidgetVersion version(majorV, minorV, microV, optionalV); + + RUNNER_ASSERT(version.IsWac() == true); + RUNNER_ASSERT(version.Major() == majorV); + RUNNER_ASSERT(version.Minor() == minorV); + RUNNER_ASSERT(version.Micro() == microV); + RUNNER_ASSERT(version.Optional() == optionalV); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_M4_O2_1 +Description: Tests if version is recognized as wac version number. +Expected: major, minor, micro and optional parts matches expected values. + Version should be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_M4_O2_nonwac_1) +{ + WidgetVersion version(L"1", L"1", DPL::Optional(L"a1"), DPL::Optional(L"b1")); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == L"1.1.a1 b1"); +} + +/* +Name: WidgetVersion_Strange_0 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_Strange_0) +{ + DPL::String raw(L"1"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_Strange_1 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_Strange_1) +{ + DPL::String raw(L".1"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_Strange_2 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_Strange_2) +{ + DPL::String raw(L"..1"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_Strange_3 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_Strange_3) +{ + DPL::String raw(L"...1"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_Strange_4 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_Strange_4) +{ + DPL::String raw(L"qwerty"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_Strange_5 +Description: tests if version is recognized as wac version number +Expected: version should not be recognized as wac compatible +*/ +RUNNER_TEST(WidgetVersion_Strange_5) +{ + DPL::String raw(L"!@#$%^&*()_+ ^&%^*&%$^*&%*()& JHKJLHKJLH 685685687"); + WidgetVersion version(raw); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == raw); +} + +/* +Name: WidgetVersion_Strange_6 +Description: Tests if version is recognized as wac version number. +Expected: Version should not be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_Strange_6) +{ + WidgetVersion version(L"1", L"", DPL::Optional(), DPL::Optional()); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == L"1."); +} + +/* +Name: WidgetVersion_Strange_7 +Description: Tests if version is recognized as wac version number. +Expected: Version should not be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_Strange_7) +{ + WidgetVersion version(L"a", L"b", DPL::Optional(), DPL::Optional()); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == L"a.b"); +} + +/* +Name: WidgetVersion_Strange_8 +Description: Tests if version is recognized as wac version number. +Expected: Version should not be recognized as wac compatible. +*/ +RUNNER_TEST(WidgetVersion_Strange_8) +{ + WidgetVersion version(L"", L"", DPL::Optional(L"12"), DPL::Optional(L"abcd123")); + + RUNNER_ASSERT(version.IsWac() == false); + RUNNER_ASSERT(version.Raw() == L"..12 abcd123"); +} + +/* +Name: WidgetVersion_Compare_0 +Description: Tests versions comparision by less than operator. +Expected: Compare should work as expected. +*/ +RUNNER_TEST(WidgetVersion_Compare_0) +{ + RUNNER_ASSERT(WidgetVersion(L"1.1") < WidgetVersion(L"1.2")); + RUNNER_ASSERT(WidgetVersion(L"01.001") < WidgetVersion(L"0001.002")); + RUNNER_ASSERT(WidgetVersion(L"01.001") < WidgetVersion(L"0001.0010")); + RUNNER_ASSERT(WidgetVersion(L"01.001.01") < WidgetVersion(L"0001.001.012 abc")); + RUNNER_ASSERT(WidgetVersion(L"087654321.0123456789") < WidgetVersion(L"0987654321.0123456789")); +} + +/* +Name: WidgetVersion_Compare_1 +Description: Tests versions comparision by more than operator. +Expected: Compare should work as expected. +*/ +RUNNER_TEST(WidgetVersion_Compare_1) +{ + RUNNER_ASSERT(WidgetVersion(L"1.2") > WidgetVersion(L"1.1")); + RUNNER_ASSERT(WidgetVersion(L"1.020") > WidgetVersion(L"0001.00002")); + RUNNER_ASSERT(WidgetVersion(L"01.0020") > WidgetVersion(L"0001.001")); + RUNNER_ASSERT(WidgetVersion(L"0001.0020.01") > WidgetVersion(L"01.0002.0 abcd")); + RUNNER_ASSERT(WidgetVersion( + L"19647963733338932479072098437089778943732432.00000000000000004324324324324321") + > WidgetVersion(L"4324324324324324324321.000432")); +} + +/* +Name: WidgetVersion_Compare_2 +Description: Tests versions comparision by less than or equal operator. +Expected: Compare should work as expected. +*/ +RUNNER_TEST(WidgetVersion_Compare_2) +{ + RUNNER_ASSERT(WidgetVersion(L"1.1") <= WidgetVersion(L"01.2")); + RUNNER_ASSERT(WidgetVersion(L"0001.02") <= WidgetVersion(L"1.02")); + RUNNER_ASSERT(WidgetVersion(L"001.002") <= WidgetVersion(L"0002.002")); + RUNNER_ASSERT(WidgetVersion(L"2.00000000000000") <= + WidgetVersion(L"2.0 test")); +} + +/* +Name: WidgetVersion_Compare_3 +Description: Tests versions comparision more than or equal operator. +Expected: Compare should work as expected. +*/ +RUNNER_TEST(WidgetVersion_Compare_3) +{ + RUNNER_ASSERT(WidgetVersion(L"1.2") >= WidgetVersion(L"1.1")); + RUNNER_ASSERT(WidgetVersion(L"1.20") >= WidgetVersion(L"01.2")); + RUNNER_ASSERT(WidgetVersion(L"001.20") >= WidgetVersion(L"01.0020")); + RUNNER_ASSERT(WidgetVersion(L"001.20.11") >= WidgetVersion(L"01.0020.10 abc")); + RUNNER_ASSERT(WidgetVersion(L"1.00000000000000") >= + WidgetVersion(L"1.0 test")); +} + +/* +Name: WidgetVersion_Compare_4 +Description: Tests versions comparsion by equality operator. +Expected: Versions should be equal. +*/ +RUNNER_TEST(WidgetVersion_Compare_4) +{ + RUNNER_ASSERT(WidgetVersion(L"0.1") == WidgetVersion(L"00.1")); + RUNNER_ASSERT(WidgetVersion(L"0002.0001") == WidgetVersion(L"02.01")); + RUNNER_ASSERT(WidgetVersion(L"0001.02") == WidgetVersion(L"1.02")); + RUNNER_ASSERT(WidgetVersion(L"2.0001.12") == WidgetVersion(L"002.01.12 abcd")); + RUNNER_ASSERT(WidgetVersion(L"12345.1") == WidgetVersion(L"12345.1")); + RUNNER_ASSERT(WidgetVersion(L"000123000.0 notatest") == + WidgetVersion(L"00123000.0 testtesttest")); +} + +/* +Name: WidgetVersion_Compare_5 +Description: Tests versions comparsion by inequality operator. +Expected: Versions should not be equal. +*/ +RUNNER_TEST(WidgetVersion_Compare_5) +{ + RUNNER_ASSERT(WidgetVersion(L"1.1") != WidgetVersion(L"1.11")); + RUNNER_ASSERT(WidgetVersion(L"2.1.1") != WidgetVersion(L"2.1.11")); + RUNNER_ASSERT(WidgetVersion(L"003.10.1") != WidgetVersion(L"3.10.11")); + RUNNER_ASSERT(WidgetVersion(L"4.2.1 abc") != WidgetVersion(L"4.2.11 abc")); +} + +/* +Name: WidgetVersion_Compare_6 +Description: Tests insertin WidgetVersion object into a stream (operator<<) +Expected: Version should be successfully inserted into a stream. +*/ +RUNNER_TEST(WidgetVersion_Compare_6) +{ + std::stringbuf buf; + std::ostream stream(&buf); + DPL::String raw(L"1.1"); + + stream << WidgetVersion(raw); + + RUNNER_ASSERT(DPL::StringCompare(raw, DPL::FromASCIIString(buf.str())) == 0); +} diff --git a/tests/utils/wrt_utility.cpp b/tests/utils/wrt_utility.cpp new file mode 100644 index 0000000..710b578 --- /dev/null +++ b/tests/utils/wrt_utility.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file wrt_utility.cpp + * @author Janusz Majnert (j.majnert@samsung.com) + * @version 1.0 + * @brief Implementation file for test cases for wrt_utility functions + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +RUNNER_TEST_GROUP_INIT(DPL_WRT_UTILITY) + +/* +Name: wrt_utility_WrtUtilJoinPaths +Description: join paths test +Expected: correctly used separator +*/ +RUNNER_TEST(wrt_utility_WrtUtilJoinPaths) +{ + std::string result; + + WrtUtilJoinPaths(result, "a/b/c/", "e/f/g.asd"); + RUNNER_ASSERT(result == "a/b/c/e/f/g.asd"); + + WrtUtilJoinPaths(result, "/a/b/c", "/e/f/g/"); + RUNNER_ASSERT(result == "/a/b/c/e/f/g/"); + + WrtUtilJoinPaths(result, "/a/b/c/", "/e/f/g/"); + RUNNER_ASSERT(result == "/a/b/c/e/f/g/"); + + WrtUtilJoinPaths(result, "/a/b/c", "e/f/g/"); + RUNNER_ASSERT(result == "/a/b/c/e/f/g/"); +} + +/** + * Create recursive path with specified permissions. + * Check if folders exist. + * Check if permissions are set. + */ +RUNNER_TEST(wrt_utility_WrtUtilMakeDir) +{ + struct stat st; + //First delete the dir if it exists + WrtUtilRemove("/tmp/test"); + WrtUtilMakeDir("/tmp/test/1/2/3/4/5/6/7/8/9", 0755); + if (stat("/tmp/test/1/2/3/4/5/6/7/8/9", &st) == 0) { + RUNNER_ASSERT_MSG(st.st_mode & S_IRWXU, + "read, write, execute/search by owner"); + RUNNER_ASSERT_MSG(st.st_mode & S_IXGRP, + "execute/search permission, group"); + RUNNER_ASSERT_MSG(st.st_mode & S_IRGRP, "read permission, group"); + RUNNER_ASSERT_MSG(!(st.st_mode & S_IWGRP), + "NO write permission, group "); + RUNNER_ASSERT_MSG(st.st_mode & S_IXOTH, + "execute/search permission, others"); + RUNNER_ASSERT_MSG(st.st_mode & S_IROTH, "read permission, others"); + RUNNER_ASSERT_MSG(!(st.st_mode & S_IWOTH), + "NO write permission, others "); + } else { + RUNNER_ASSERT_MSG(false, "Cannot stat folder"); + } +} + +/** + * Create directory without permission to write. + */ +RUNNER_TEST(wrt_utility_WrtUtilMakeDir_PermissionError) +{ + if (0 == getuid()) { + int bufsize; + if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) + RUNNER_ASSERT_MSG(false, + "Getting an initial value suggested for the size of buffer failed."); + + //Change UID to execute the test correctly + errno = 0; + char *buffer = new char[bufsize]; + struct passwd p; + struct passwd *result = NULL; + int return_value = getpwnam_r("app", &p, buffer, bufsize, &result); + delete[] buffer; + + if (return_value != 0 || !result) { + int error = errno; + RUNNER_ASSERT_MSG(false, "Getting app user UID failed: " + << (error == + 0 ? "No error detected" : strerror(error))); + } + if (setuid(p.pw_uid) != 0) { + int error = errno; + RUNNER_ASSERT_MSG(false, "Changing to app user's UID failed: " + << (error == + 0 ? "No error detected" : strerror(error))); + } + } + RUNNER_ASSERT_MSG(WrtUtilMakeDir("/tmp/test2/1", + 0055) == false, + "Creating directory '1' in /temp/test2/ should have failed"); + //Going back to root UID + if (setuid(0) != 0) { + int error = errno; + LogWarning("Changing back to root UID failed: " + << (error == 0 ? "No error detected" : strerror(error))); + } +} + +/** + * Create directory with file inside. + * Check if file was removed with directory. + */ +RUNNER_TEST(wrt_utility_WrtUtilRemoveDir) { + RUNNER_ASSERT_MSG(WrtUtilMakeDir("/tmp/test3/", 0755) == true, + "Could not set up directory for test"); + + std::ofstream file; + file.open("/tmp/test3/example.txt"); + file.close(); + struct stat tmp; + RUNNER_ASSERT_MSG(stat("/tmp/test3/example.txt", &tmp) == 0, + "Couldn't create the test file"); + + WrtUtilRemove("/tmp/test3"); + if (stat("/tmp/test3", &tmp) != 0) { + int error = errno; + RUNNER_ASSERT(error == ENOENT); + return; + } + RUNNER_ASSERT(false); +} + +/** + * Try to remove not existing folder. + */ +RUNNER_TEST(wrt_utility_WrtUtilRemoveDir_NoDirError) +{ + //First making sure the test dir doesn't exist + WrtUtilRemove("/tmp/NOT_EXISTING"); + + RUNNER_ASSERT_MSG(WrtUtilRemove("/tmp/NOT_EXISTING") == false, + "Removing non existing directory returned success"); +} + +/* +Name: wrt_utility_WrtUtilFileExists +Description: tests file existence +Expected: existing file should be reported as existing +*/ +RUNNER_TEST(wrt_utility_WrtUtilFileExists) +{ + std::ofstream file; + file.open("/tmp/test_file1"); + file.close(); + RUNNER_ASSERT(WrtUtilFileExists("/tmp/test_file1")); + + WrtUtilRemove("/tmp/test_file1"); + RUNNER_ASSERT(WrtUtilFileExists("/tmp/test_file1") == false); +} + +/* +Name: wrt_utility_WrtUtilDirExists +Description: tests directory existence +Expected: existing directory should be reported as existing +*/ +RUNNER_TEST(wrt_utility_WrtUtilDirExists) +{ + RUNNER_ASSERT(WrtUtilDirExists("/tmp")); + RUNNER_ASSERT(WrtUtilDirExists("/UNAVAILABLE_DIR") == false); +} diff --git a/uncrustify.cfg b/uncrustify.cfg new file mode 100644 index 0000000..2bf1d96 --- /dev/null +++ b/uncrustify.cfg @@ -0,0 +1,170 @@ +indent_align_string=true +indent_braces=false +indent_braces_no_func=false +indent_brace_parent=false +indent_namespace=false +indent_extern=false +indent_class=true +indent_class_colon=false +indent_else_if=false +indent_func_call_param=false +indent_func_def_param=false +indent_func_proto_param=false +indent_func_class_param=false +indent_func_ctor_var_param=false +indent_template_param=false +indent_func_param_double=false +indent_relative_single_line_comments=false +indent_col1_comment=true +indent_access_spec_body=false +indent_paren_nl=false +indent_comma_paren=false +indent_bool_paren=false +indent_square_nl=false +indent_preserve_sql=false +indent_align_assign=false +sp_balance_nested_parens=false +align_keep_tabs=false +align_with_tabs=false +align_on_tabstop=false +align_number_left=false +align_func_params=false +align_same_func_call_params=false +align_var_def_colon=false +align_var_def_attribute=false +align_var_def_inline=false +align_right_cmt_mix=false +align_on_operator=false +align_mix_var_proto=false +align_single_line_func=false +align_single_line_brace=false +align_nl_cont=false +align_left_shift=true +nl_collapse_empty_body=true +nl_assign_leave_one_liners=false +nl_class_leave_one_liners=false +nl_enum_leave_one_liners=false +nl_getset_leave_one_liners=false +nl_func_leave_one_liners=false +nl_if_leave_one_liners=false +nl_multi_line_cond=true +nl_multi_line_define=false +nl_before_case=false +nl_after_case=false +nl_after_return=false +nl_after_semicolon=true +nl_after_brace_open=false +nl_after_brace_open_cmt=false +nl_after_vbrace_open=false +nl_after_brace_close=false +nl_define_macro=false +nl_squeeze_ifdef=false +nl_ds_struct_enum_cmt=false +nl_ds_struct_enum_close_brace=false +nl_create_if_one_liner=false +nl_create_for_one_liner=false +nl_create_while_one_liner=false +ls_for_split_full=true +ls_func_split_full=true +nl_after_multiline_comment=false +eat_blanks_after_open_brace=true +eat_blanks_before_close_brace=true +mod_pawn_semicolon=false +mod_full_paren_if_bool=false +mod_remove_extra_semicolon=true +mod_sort_import=false +mod_sort_using=false +mod_sort_include=false +mod_move_case_break=false +mod_remove_empty_return=false +cmt_indent_multi=true +cmt_c_group=false +cmt_c_nl_start=false +cmt_c_nl_end=false +cmt_cpp_group=false +cmt_cpp_nl_start=false +cmt_cpp_nl_end=false +cmt_cpp_to_c=false +cmt_star_cont=true +cmt_multi_check_last=true +cmt_insert_before_preproc=false +pp_indent_at_level=false +pp_region_indent_code=false +pp_if_indent_code=false +pp_define_at_level=false +indent_columns=4 +indent_member=4 +indent_access_spec=-2 +code_width=80 +nl_max=2 +nl_before_access_spec=2 +cmt_width=80 +indent_with_tabs=0 +sp_arith=force +sp_assign=force +sp_enum_assign=force +sp_pp_concat=remove +sp_pp_stringify=remove +sp_bool=force +sp_compare=force +sp_paren_brace=force +sp_angle_paren=remove +sp_before_sparen=force +sp_inside_sparen=remove +sp_after_sparen=force +sp_sparen_brace=force +sp_before_semi=remove +sp_after_semi_for_empty=remove +sp_before_square=remove +sp_before_squares=remove +sp_inside_square=remove +sp_after_comma=force +sp_before_comma=remove +sp_after_class_colon=force +sp_before_class_colon=force +sp_before_case_colon=remove +sp_inside_braces=add +sp_inside_fparens=remove +sp_inside_fparen=remove +sp_func_call_paren=remove +sp_func_class_paren=remove +sp_else_brace=force +sp_brace_else=force +sp_catch_brace=force +sp_brace_catch=force +sp_try_brace=force +sp_before_dc=remove +sp_after_dc=remove +sp_not=remove +sp_inv=remove +sp_addr=remove +sp_member=remove +sp_deref=remove +sp_sign=remove +sp_incdec=remove +sp_cond_colon=force +sp_cond_question=force +sp_case_label=force +nl_assign_brace=remove +nl_if_brace=remove +nl_brace_else=remove +nl_elseif_brace=remove +nl_else_brace=remove +nl_else_if=remove +nl_try_brace=remove +nl_for_brace=remove +nl_catch_brace=remove +nl_brace_catch=remove +nl_while_brace=remove +nl_do_brace=remove +nl_brace_while=remove +nl_switch_brace=remove +nl_namespace_brace=remove +nl_class_brace=force +nl_fdef_brace=force +pos_class_comma=trail +pos_class_colon=trail +mod_full_brace_do=add +mod_full_brace_for=add +mod_full_brace_if=add +mod_full_brace_while=add diff --git a/uncrustify.sh b/uncrustify.sh new file mode 100755 index 0000000..2ccffef --- /dev/null +++ b/uncrustify.sh @@ -0,0 +1 @@ +uncrustify -c uncrustify.cfg --no-backup `find . -regex "\(.*\.cpp\|.*\.h\|.*\.c\|.*\.cc\)" | grep -v "orm.h\|orm_generator.h\|examples"` diff --git a/wrt-commons b/wrt-commons new file mode 100644 index 0000000..a285a63 --- /dev/null +++ b/wrt-commons @@ -0,0 +1,204 @@ +wrt-commons: +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/wrt-commons.manifest b/wrt-commons.manifest new file mode 100644 index 0000000..6b910cf --- /dev/null +++ b/wrt-commons.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + + + +