tizen 2.3.1 release accepted/tizen_2.3.1_wearable tizen_2.3.1 accepted/tizen/2.3.1/wearable/20160306.221732 submit/tizen_2.3.1/20150915.091051 submit/tizen_2.3.1/20160304.093529 tizen_2.3.1_release
authorjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 16:33:31 +0000 (01:33 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 16:33:31 +0000 (01:33 +0900)
540 files changed:
.gitignore [new file with mode: 0755]
CMakeLists.txt [new file with mode: 0644]
LICENSE [new file with mode: 0644]
NOTICE [new file with mode: 0644]
build/CMakeLists.txt [new file with mode: 0644]
build/certificate_dao/CMakeLists.txt [new file with mode: 0755]
build/certificate_dao/wrt-commons-certificate-dao.pc.in [new file with mode: 0644]
build/core/CMakeLists.txt [new file with mode: 0644]
build/core/DESCRIPTION [new file with mode: 0644]
build/core/dpl-efl.pc.in [new file with mode: 0644]
build/custom_handler_dao/CMakeLists.txt [new file with mode: 0644]
build/custom_handler_dao/wrt-commons-custom-handler-dao-ro.pc.in [new file with mode: 0644]
build/custom_handler_dao/wrt-commons-custom-handler-dao-rw.pc.in [new file with mode: 0644]
build/db/CMakeLists.txt [new file with mode: 0644]
build/db/dpl-db-efl.pc.in [new file with mode: 0644]
build/dbus/CMakeLists.txt [new file with mode: 0644]
build/dbus/dpl-dbus-efl.pc.in [new file with mode: 0644]
build/event/CMakeLists.txt [new file with mode: 0644]
build/event/dpl-event-efl.pc.in [new file with mode: 0644]
build/i18n/CMakeLists.txt [new file with mode: 0644]
build/i18n/wrt-commons-i18n-dao-ro.pc.in [new file with mode: 0644]
build/log/CMakeLists.txt [new file with mode: 0644]
build/log/dpl-log-efl.pc.in [new file with mode: 0644]
build/rpc/CMakeLists.txt [new file with mode: 0644]
build/rpc/dpl-rpc-efl.pc.in [new file with mode: 0644]
build/security_origin_dao/CMakeLists.txt [new file with mode: 0644]
build/security_origin_dao/wrt-commons-security-origin-dao.pc.in [new file with mode: 0644]
build/socket/CMakeLists.txt [new file with mode: 0644]
build/socket/dpl-socket-efl.pc.in [new file with mode: 0644]
build/support/CMakeLists.txt [new file with mode: 0644]
build/support/wrt-plugins-types.pc.in [new file with mode: 0644]
build/test/CMakeLists.txt [new file with mode: 0644]
build/test/dpl-test-efl.pc.in [new file with mode: 0644]
build/utils/CMakeLists.txt [new file with mode: 0644]
build/utils/dpl-utils-efl.pc.in [new file with mode: 0644]
build/widget_dao/CMakeLists.txt [new file with mode: 0644]
build/widget_dao/dpl-wrt-dao-ro.pc.in [new file with mode: 0644]
build/widget_dao/dpl-wrt-dao-rw.pc.in [new file with mode: 0644]
build/widget_interface_dao/CMakeLists.txt [new file with mode: 0644]
build/widget_interface_dao/wrt-commons-widget-interface-dao.pc.in [new file with mode: 0644]
dir-struct.py [new file with mode: 0755]
doc/DESCRIPTION [new file with mode: 0644]
doc/doxyfile [new file with mode: 0644]
doc/dpl_programming_guide.docx [new file with mode: 0644]
doc/dpl_programming_guide.pdf [new file with mode: 0644]
etc/CMakeLists.txt [new file with mode: 0644]
etc/DESCRIPTION [new file with mode: 0644]
etc/wrt_commons_create_clean_db.sh [new file with mode: 0755]
etc/wrt_commons_reset_db.sh [new file with mode: 0755]
examples/CMakeLists.txt [new file with mode: 0644]
examples/DESCRIPTION [new file with mode: 0644]
examples/binary_queue/CMakeLists.txt [new file with mode: 0644]
examples/binary_queue/binary_queue.cpp [new file with mode: 0644]
examples/copy/CMakeLists.txt [new file with mode: 0644]
examples/copy/copy.cpp [new file with mode: 0644]
examples/crypto_hash/CMakeLists.txt [new file with mode: 0644]
examples/crypto_hash/crypto_hash.cpp [new file with mode: 0644]
examples/dbus/client-example/CMakeLists.txt [new file with mode: 0755]
examples/dbus/client-example/client-example.cpp [new file with mode: 0644]
examples/dbus/server-example/CMakeLists.txt [new file with mode: 0755]
examples/dbus/server-example/server-example.cpp [new file with mode: 0644]
examples/fake_rpc/CMakeLists.txt [new file with mode: 0644]
examples/fake_rpc/fake_rpc.cpp [new file with mode: 0644]
examples/metronome/CMakeLists.txt [new file with mode: 0644]
examples/metronome/metronome_client.cpp [new file with mode: 0644]
examples/metronome/metronome_server.cpp [new file with mode: 0644]
examples/rpc/CMakeLists.txt [new file with mode: 0644]
examples/rpc/rpc.cpp [new file with mode: 0644]
examples/simple/CMakeLists.txt [new file with mode: 0644]
examples/simple/simple.cpp [new file with mode: 0644]
examples/single_instance/CMakeLists.txt [new file with mode: 0644]
examples/single_instance/single_instance.cpp [new file with mode: 0644]
examples/socket/CMakeLists.txt [new file with mode: 0644]
examples/socket/socket.cpp [new file with mode: 0644]
examples/tcpsock/CMakeLists.txt [new file with mode: 0644]
examples/tcpsock/tcpsock.cpp [new file with mode: 0644]
examples/timed_event/CMakeLists.txt [new file with mode: 0644]
examples/timed_event/timed_event.cpp [new file with mode: 0644]
modules/CMakeLists.txt [new file with mode: 0644]
modules/certificate_dao/CMakeLists.txt [new file with mode: 0755]
modules/certificate_dao/dao/certificate_dao.cpp [new file with mode: 0644]
modules/certificate_dao/dao/certificate_dao_types.cpp [new file with mode: 0755]
modules/certificate_dao/dao/certificate_database.cpp [new file with mode: 0755]
modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_dao.h [new file with mode: 0644]
modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_dao_types.h [new file with mode: 0755]
modules/certificate_dao/include/wrt-commons/certificate-dao/certificate_database.h [new file with mode: 0755]
modules/certificate_dao/orm/certificate_db [new file with mode: 0755]
modules/certificate_dao/orm/certificate_db_definitions [new file with mode: 0644]
modules/certificate_dao/orm/certificate_db_sql_generator.h [new file with mode: 0755]
modules/certificate_dao/orm/orm_generator_certificate.h [new file with mode: 0755]
modules/core/DESCRIPTION [new file with mode: 0644]
modules/core/config.cmake [new file with mode: 0644]
modules/core/include/DESCRIPTION [new file with mode: 0644]
modules/core/include/dpl/abstract_input.h [new file with mode: 0644]
modules/core/include/dpl/abstract_input_output.h [new file with mode: 0644]
modules/core/include/dpl/abstract_output.h [new file with mode: 0644]
modules/core/include/dpl/abstract_waitable_input.h [new file with mode: 0644]
modules/core/include/dpl/abstract_waitable_input_adapter.h [new file with mode: 0644]
modules/core/include/dpl/abstract_waitable_input_output.h [new file with mode: 0644]
modules/core/include/dpl/abstract_waitable_input_output_adapter.h [new file with mode: 0644]
modules/core/include/dpl/abstract_waitable_output.h [new file with mode: 0644]
modules/core/include/dpl/abstract_waitable_output_adapter.h [new file with mode: 0644]
modules/core/include/dpl/address.h [new file with mode: 0644]
modules/core/include/dpl/aligned.h [new file with mode: 0644]
modules/core/include/dpl/application.h [new file with mode: 0644]
modules/core/include/dpl/apply.h [new file with mode: 0644]
modules/core/include/dpl/assert.h [new file with mode: 0644]
modules/core/include/dpl/atomic.h [new file with mode: 0644]
modules/core/include/dpl/availability.h [new file with mode: 0644]
modules/core/include/dpl/binary_queue.h [new file with mode: 0644]
modules/core/include/dpl/bind.h [new file with mode: 0644]
modules/core/include/dpl/bool_operator.h [new file with mode: 0644]
modules/core/include/dpl/char_traits.h [new file with mode: 0644]
modules/core/include/dpl/colors.h [new file with mode: 0644]
modules/core/include/dpl/copy.h [new file with mode: 0644]
modules/core/include/dpl/enable_shared_from_this.h [new file with mode: 0644]
modules/core/include/dpl/errno_string.h [new file with mode: 0644]
modules/core/include/dpl/exception.h [new file with mode: 0644]
modules/core/include/dpl/file_input.h [new file with mode: 0644]
modules/core/include/dpl/file_output.h [new file with mode: 0644]
modules/core/include/dpl/foreach.h [new file with mode: 0644]
modules/core/include/dpl/framework_appcore.h [new file with mode: 0644]
modules/core/include/dpl/framework_efl.h [new file with mode: 0644]
modules/core/include/dpl/framework_vconf.h [new file with mode: 0644]
modules/core/include/dpl/generic_event.h [new file with mode: 0644]
modules/core/include/dpl/lexical_cast.h [new file with mode: 0644]
modules/core/include/dpl/main.h [new file with mode: 0644]
modules/core/include/dpl/mutable_task_list.h [new file with mode: 0644]
modules/core/include/dpl/mutex.h [new file with mode: 0644]
modules/core/include/dpl/named_base_pipe.h [new file with mode: 0644]
modules/core/include/dpl/named_input_pipe.h [new file with mode: 0644]
modules/core/include/dpl/named_output_pipe.h [new file with mode: 0644]
modules/core/include/dpl/noncopyable.h [new file with mode: 0644]
modules/core/include/dpl/once.h [new file with mode: 0644]
modules/core/include/dpl/optional.h [new file with mode: 0644]
modules/core/include/dpl/optional_typedefs.h [new file with mode: 0644]
modules/core/include/dpl/platform.h [new file with mode: 0644]
modules/core/include/dpl/preprocessor.h [new file with mode: 0644]
modules/core/include/dpl/read_write_mutex.h [new file with mode: 0644]
modules/core/include/dpl/recursive_mutex.h [new file with mode: 0644]
modules/core/include/dpl/scope_guard.h [new file with mode: 0644]
modules/core/include/dpl/scoped_array.h [new file with mode: 0644]
modules/core/include/dpl/scoped_close.h [new file with mode: 0644]
modules/core/include/dpl/scoped_dir.h [new file with mode: 0644]
modules/core/include/dpl/scoped_fclose.h [new file with mode: 0644]
modules/core/include/dpl/scoped_free.h [new file with mode: 0644]
modules/core/include/dpl/scoped_gpointer.h [new file with mode: 0644]
modules/core/include/dpl/scoped_ptr.h [new file with mode: 0644]
modules/core/include/dpl/scoped_resource.h [new file with mode: 0644]
modules/core/include/dpl/semaphore.h [new file with mode: 0644]
modules/core/include/dpl/serialization.h [new file with mode: 0644]
modules/core/include/dpl/shared_ptr.h [new file with mode: 0644]
modules/core/include/dpl/single_instance.h [new file with mode: 0644]
modules/core/include/dpl/singleton.h [new file with mode: 0644]
modules/core/include/dpl/singleton_impl.h [new file with mode: 0644]
modules/core/include/dpl/singleton_safe_impl.h [new file with mode: 0644]
modules/core/include/dpl/sstream.h [new file with mode: 0644]
modules/core/include/dpl/static_block.h [new file with mode: 0644]
modules/core/include/dpl/string.h [new file with mode: 0644]
modules/core/include/dpl/task.h [new file with mode: 0644]
modules/core/include/dpl/thread.h [new file with mode: 0644]
modules/core/include/dpl/type_list.h [new file with mode: 0644]
modules/core/include/dpl/union_cast.h [new file with mode: 0644]
modules/core/include/dpl/waitable_event.h [new file with mode: 0644]
modules/core/include/dpl/waitable_handle.h [new file with mode: 0644]
modules/core/include/dpl/waitable_handle_watch_support.h [new file with mode: 0644]
modules/core/include/dpl/workaround.h [new file with mode: 0644]
modules/core/include/dpl/zip_input.h [new file with mode: 0644]
modules/core/src/DESCRIPTION [new file with mode: 0644]
modules/core/src/abstract_waitable_input_adapter.cpp [new file with mode: 0644]
modules/core/src/abstract_waitable_input_output_adapter.cpp [new file with mode: 0644]
modules/core/src/abstract_waitable_output_adapter.cpp [new file with mode: 0644]
modules/core/src/address.cpp [new file with mode: 0644]
modules/core/src/application.cpp [new file with mode: 0644]
modules/core/src/apply.cpp [new file with mode: 0644]
modules/core/src/assert.cpp [new file with mode: 0644]
modules/core/src/atomic.cpp [new file with mode: 0644]
modules/core/src/binary_queue.cpp [new file with mode: 0644]
modules/core/src/char_traits.cpp [new file with mode: 0644]
modules/core/src/colors.cpp [new file with mode: 0644]
modules/core/src/copy.cpp [new file with mode: 0644]
modules/core/src/errno_string.cpp [new file with mode: 0644]
modules/core/src/exception.cpp [new file with mode: 0644]
modules/core/src/file_input.cpp [new file with mode: 0644]
modules/core/src/file_output.cpp [new file with mode: 0644]
modules/core/src/generic_event.cpp [new file with mode: 0644]
modules/core/src/lexical_cast.cpp [new file with mode: 0644]
modules/core/src/main.cpp [new file with mode: 0644]
modules/core/src/mutable_task_list.cpp [new file with mode: 0644]
modules/core/src/mutex.cpp [new file with mode: 0644]
modules/core/src/named_base_pipe.cpp [new file with mode: 0644]
modules/core/src/named_output_pipe.cpp [new file with mode: 0644]
modules/core/src/noncopyable.cpp [new file with mode: 0644]
modules/core/src/once.cpp [new file with mode: 0644]
modules/core/src/read_write_mutex.cpp [new file with mode: 0644]
modules/core/src/recursive_mutex.cpp [new file with mode: 0644]
modules/core/src/scoped_dir.cpp [new file with mode: 0644]
modules/core/src/semaphore.cpp [new file with mode: 0644]
modules/core/src/serialization.cpp [new file with mode: 0644]
modules/core/src/single_instance.cpp [new file with mode: 0644]
modules/core/src/singleton.cpp [new file with mode: 0644]
modules/core/src/string.cpp [new file with mode: 0644]
modules/core/src/task.cpp [new file with mode: 0644]
modules/core/src/thread.cpp [new file with mode: 0644]
modules/core/src/type_list.cpp [new file with mode: 0644]
modules/core/src/union_cast.cpp [new file with mode: 0644]
modules/core/src/waitable_event.cpp [new file with mode: 0644]
modules/core/src/waitable_handle.cpp [new file with mode: 0644]
modules/core/src/waitable_handle_watch_support.cpp [new file with mode: 0644]
modules/core/src/zip_input.cpp [new file with mode: 0644]
modules/custom_handler_dao/CMakeLists.txt [new file with mode: 0644]
modules/custom_handler_dao/dao/CustomHandlerDatabase.cpp [new file with mode: 0644]
modules/custom_handler_dao/dao/custom_handler_dao.cpp [new file with mode: 0644]
modules/custom_handler_dao/dao/custom_handler_dao_read_only.cpp [new file with mode: 0644]
modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h [new file with mode: 0644]
modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/common_dao_types.h [new file with mode: 0644]
modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h [new file with mode: 0644]
modules/custom_handler_dao/include/wrt-commons/custom-handler-dao-rw/custom_handler_dao.h [new file with mode: 0644]
modules/custom_handler_dao/orm/custom_handler_db [new file with mode: 0644]
modules/custom_handler_dao/orm/custom_handler_db_definitions [new file with mode: 0644]
modules/custom_handler_dao/orm/custom_handler_db_sql_generator.h [new file with mode: 0644]
modules/custom_handler_dao/orm/gen_db_md5.sh [new file with mode: 0755]
modules/custom_handler_dao/orm/orm_generator_custom_handler.h [new file with mode: 0644]
modules/custom_handler_dao/orm/version_db [new file with mode: 0644]
modules/db/config.cmake [new file with mode: 0644]
modules/db/include/dpl/db/naive_synchronization_object.h [new file with mode: 0644]
modules/db/include/dpl/db/orm.h [new file with mode: 0644]
modules/db/include/dpl/db/orm_generator.h [new file with mode: 0644]
modules/db/include/dpl/db/orm_interface.h [new file with mode: 0644]
modules/db/include/dpl/db/orm_macros.h [new file with mode: 0644]
modules/db/include/dpl/db/sql_connection.h [new file with mode: 0644]
modules/db/include/dpl/db/thread_database_support.h [new file with mode: 0644]
modules/db/src/naive_synchronization_object.cpp [new file with mode: 0644]
modules/db/src/orm.cpp [new file with mode: 0644]
modules/db/src/sql_connection.cpp [new file with mode: 0644]
modules/db/src/thread_database_support.cpp [new file with mode: 0644]
modules/dbus/config.cmake [new file with mode: 0644]
modules/dbus/include/dpl/dbus/connection.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/dbus_client.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/dbus_deserialization.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/dbus_interface_dispatcher.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/dbus_serialization.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/dbus_server_deserialization.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/dbus_server_serialization.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/dbus_signature.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/dispatcher.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/exception.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/glib_util.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/interface.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/method_proxy.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/object.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/object_proxy.h [new file with mode: 0644]
modules/dbus/include/dpl/dbus/server.h [new file with mode: 0644]
modules/dbus/src/connection.cpp [new file with mode: 0644]
modules/dbus/src/dispatcher.cpp [new file with mode: 0644]
modules/dbus/src/interface.cpp [new file with mode: 0644]
modules/dbus/src/object.cpp [new file with mode: 0644]
modules/dbus/src/object_proxy.cpp [new file with mode: 0644]
modules/dbus/src/server.cpp [new file with mode: 0644]
modules/event/config.cmake [new file with mode: 0644]
modules/event/include/dpl/event/abstract_event_call.h [new file with mode: 0644]
modules/event/include/dpl/event/abstract_event_dispatcher.h [new file with mode: 0644]
modules/event/include/dpl/event/controller.h [new file with mode: 0644]
modules/event/include/dpl/event/event_listener.h [new file with mode: 0644]
modules/event/include/dpl/event/event_support.h [new file with mode: 0644]
modules/event/include/dpl/event/generic_event_call.h [new file with mode: 0644]
modules/event/include/dpl/event/inter_context_delegate.h [new file with mode: 0644]
modules/event/include/dpl/event/main_event_dispatcher.h [new file with mode: 0644]
modules/event/include/dpl/event/model.h [new file with mode: 0644]
modules/event/include/dpl/event/model_bind_to_dao.h [new file with mode: 0644]
modules/event/include/dpl/event/property.h [new file with mode: 0644]
modules/event/include/dpl/event/thread_event_dispatcher.h [new file with mode: 0644]
modules/event/src/abstract_event_call.cpp [new file with mode: 0644]
modules/event/src/abstract_event_dispatcher.cpp [new file with mode: 0644]
modules/event/src/controller.cpp [new file with mode: 0644]
modules/event/src/event_listener.cpp [new file with mode: 0644]
modules/event/src/event_support.cpp [new file with mode: 0644]
modules/event/src/generic_event_call.cpp [new file with mode: 0644]
modules/event/src/inter_context_delegate.cpp [new file with mode: 0644]
modules/event/src/main_event_dispatcher.cpp [new file with mode: 0644]
modules/event/src/model.cpp [new file with mode: 0644]
modules/event/src/thread_event_dispatcher.cpp [new file with mode: 0644]
modules/i18n/CMakeLists.txt [new file with mode: 0644]
modules/i18n/dao/CMakeLists.txt [new file with mode: 0644]
modules/i18n/dao/include/wrt-commons/i18n-dao-ro/i18n_dao_read_only.h [new file with mode: 0644]
modules/i18n/dao/include/wrt-commons/i18n-dao-ro/i18n_database.h [new file with mode: 0644]
modules/i18n/dao/orm/gen_db_md5.sh [new file with mode: 0755]
modules/i18n/dao/orm/i18n_db_definitions [new file with mode: 0644]
modules/i18n/dao/orm/i18n_db_sql_generator.h [new file with mode: 0644]
modules/i18n/dao/orm/iana_db [new file with mode: 0644]
modules/i18n/dao/orm/orm_generator_i18n.h [new file with mode: 0644]
modules/i18n/dao/orm/version_db [new file with mode: 0644]
modules/i18n/dao/src/i18n_dao_read_only.cpp [new file with mode: 0644]
modules/i18n/dao/src/i18n_database.cpp [new file with mode: 0644]
modules/localization/config.cmake [new file with mode: 0644]
modules/localization/include/LanguageTagsProvider.h [new file with mode: 0644]
modules/localization/include/dpl/localization/localization_utils.h [new file with mode: 0644]
modules/localization/include/dpl/localization/w3c_file_localization.h [new file with mode: 0755]
modules/localization/src/LanguageTagsProvider.cpp [new file with mode: 0644]
modules/localization/src/w3c_file_localization.cpp [new file with mode: 0644]
modules/log/config.cmake [new file with mode: 0644]
modules/log/include/dpl/log/abstract_log_provider.h [new file with mode: 0644]
modules/log/include/dpl/log/dlog_log_provider.h [new file with mode: 0644]
modules/log/include/dpl/log/log.h [new file with mode: 0644]
modules/log/include/dpl/log/old_style_log_provider.h [new file with mode: 0644]
modules/log/include/dpl/log/secure_log.h [new file with mode: 0644]
modules/log/src/abstract_log_provider.cpp [new file with mode: 0644]
modules/log/src/dlog_log_provider.cpp [new file with mode: 0644]
modules/log/src/log.cpp [new file with mode: 0644]
modules/log/src/old_style_log_provider.cpp [new file with mode: 0644]
modules/rpc/config.cmake [new file with mode: 0644]
modules/rpc/include/dpl/rpc/abstract_rpc_connection.h [new file with mode: 0644]
modules/rpc/include/dpl/rpc/abstract_rpc_connector.h [new file with mode: 0644]
modules/rpc/include/dpl/rpc/generic_rpc_connection.h [new file with mode: 0644]
modules/rpc/include/dpl/rpc/generic_socket_rpc_client.h [new file with mode: 0644]
modules/rpc/include/dpl/rpc/generic_socket_rpc_connection.h [new file with mode: 0644]
modules/rpc/include/dpl/rpc/generic_socket_rpc_server.h [new file with mode: 0644]
modules/rpc/include/dpl/rpc/rpc_function.h [new file with mode: 0644]
modules/rpc/include/dpl/rpc/unix_socket_rpc_client.h [new file with mode: 0644]
modules/rpc/include/dpl/rpc/unix_socket_rpc_connection.h [new file with mode: 0644]
modules/rpc/include/dpl/rpc/unix_socket_rpc_server.h [new file with mode: 0644]
modules/rpc/src/abstract_rpc_connection.cpp [new file with mode: 0644]
modules/rpc/src/abstract_rpc_connector.cpp [new file with mode: 0644]
modules/rpc/src/generic_rpc_connection.cpp [new file with mode: 0644]
modules/rpc/src/generic_socket_rpc_client.cpp [new file with mode: 0644]
modules/rpc/src/generic_socket_rpc_connection.cpp [new file with mode: 0644]
modules/rpc/src/generic_socket_rpc_server.cpp [new file with mode: 0644]
modules/rpc/src/unix_socket_rpc_client.cpp [new file with mode: 0644]
modules/rpc/src/unix_socket_rpc_connection.cpp [new file with mode: 0644]
modules/rpc/src/unix_socket_rpc_server.cpp [new file with mode: 0644]
modules/security_origin_dao/CMakeLists.txt [new file with mode: 0644]
modules/security_origin_dao/dao/security_origin_dao.cpp [new file with mode: 0644]
modules/security_origin_dao/dao/security_origin_dao_types.cpp [new file with mode: 0755]
modules/security_origin_dao/include/wrt-commons/security-origin-dao/security_origin_dao.h [new file with mode: 0644]
modules/security_origin_dao/include/wrt-commons/security-origin-dao/security_origin_dao_types.h [new file with mode: 0755]
modules/security_origin_dao/orm/orm_generator_security_origin.h [new file with mode: 0644]
modules/security_origin_dao/orm/security_origin_db [new file with mode: 0644]
modules/security_origin_dao/orm/security_origin_db_definitions [new file with mode: 0644]
modules/security_origin_dao/orm/security_origin_db_sql_generator.h [new file with mode: 0644]
modules/socket/config.cmake [new file with mode: 0644]
modules/socket/include/dpl/socket/abstract_socket.h [new file with mode: 0644]
modules/socket/include/dpl/socket/generic_socket.h [new file with mode: 0644]
modules/socket/include/dpl/socket/unix_socket.h [new file with mode: 0644]
modules/socket/include/dpl/socket/waitable_input_output_execution_context_support.h [new file with mode: 0644]
modules/socket/src/generic_socket.cpp [new file with mode: 0644]
modules/socket/src/unix_socket.cpp [new file with mode: 0644]
modules/socket/src/waitable_input_output_execution_context_support.cpp [new file with mode: 0644]
modules/support/config.cmake [new file with mode: 0644]
modules/support/wrt_plugin_export.h [new file with mode: 0755]
modules/test/config.cmake [new file with mode: 0644]
modules/test/include/dpl/test/abstract_input_parser.h [new file with mode: 0644]
modules/test/include/dpl/test/abstract_input_reader.h [new file with mode: 0644]
modules/test/include/dpl/test/abstract_input_tokenizer.h [new file with mode: 0644]
modules/test/include/dpl/test/process_pipe.h [new file with mode: 0644]
modules/test/include/dpl/test/test_results_collector.h [new file with mode: 0644]
modules/test/include/dpl/test/test_runner.h [new file with mode: 0644]
modules/test/include/dpl/test/test_runner_child.h [new file with mode: 0644]
modules/test/include/dpl/test/test_runner_multiprocess.h [new file with mode: 0644]
modules/test/include/dpl/test/value_separated_parser.h [new file with mode: 0644]
modules/test/include/dpl/test/value_separated_policies.h [new file with mode: 0644]
modules/test/include/dpl/test/value_separated_reader.h [new file with mode: 0644]
modules/test/include/dpl/test/value_separated_tokenizer.h [new file with mode: 0644]
modules/test/include/dpl/test/value_separated_tokens.h [new file with mode: 0644]
modules/test/src/process_pipe.cpp [new file with mode: 0644]
modules/test/src/test_results_collector.cpp [new file with mode: 0644]
modules/test/src/test_runner.cpp [new file with mode: 0644]
modules/test/src/test_runner_child.cpp [new file with mode: 0644]
modules/test/src/test_runner_multiprocess.cpp [new file with mode: 0644]
modules/test/src/value_separated_policies.cpp [new file with mode: 0644]
modules/test/src/value_separated_tokens.cpp [new file with mode: 0644]
modules/utils/config.cmake [new file with mode: 0644]
modules/utils/include/dpl/utils/bash_utils.h [new file with mode: 0644]
modules/utils/include/dpl/utils/folder_size.h [new file with mode: 0644]
modules/utils/include/dpl/utils/mime_type_utils.h [new file with mode: 0644]
modules/utils/include/dpl/utils/path.h [new file with mode: 0644]
modules/utils/include/dpl/utils/warp_iri.h [new file with mode: 0644]
modules/utils/include/dpl/utils/widget_version.h [new file with mode: 0644]
modules/utils/include/dpl/utils/wrt_global_settings.h [new file with mode: 0644]
modules/utils/include/dpl/utils/wrt_utility.h [new file with mode: 0644]
modules/utils/src/bash_utils.cpp [new file with mode: 0644]
modules/utils/src/folder_size.cpp [new file with mode: 0644]
modules/utils/src/mime_type_utils.cpp [new file with mode: 0644]
modules/utils/src/path.cpp [new file with mode: 0644]
modules/utils/src/warp_iri.cpp [new file with mode: 0644]
modules/utils/src/widget_version.cpp [new file with mode: 0644]
modules/utils/src/wrt_global_settings.cpp [new file with mode: 0644]
modules/utils/src/wrt_utility.cpp [new file with mode: 0644]
modules/widget_dao/CMakeLists.txt [new file with mode: 0644]
modules/widget_dao/dao/WrtDatabase.cpp [new file with mode: 0644]
modules/widget_dao/dao/common_dao_types.cpp [new file with mode: 0644]
modules/widget_dao/dao/config_parser_data.cpp [new file with mode: 0644]
modules/widget_dao/dao/feature_dao.cpp [new file with mode: 0644]
modules/widget_dao/dao/feature_dao_read_only.cpp [new file with mode: 0644]
modules/widget_dao/dao/path_builder.cpp [new file with mode: 0644]
modules/widget_dao/dao/plugin_dao.cpp [new file with mode: 0644]
modules/widget_dao/dao/plugin_dao_read_only.cpp [new file with mode: 0644]
modules/widget_dao/dao/property_dao.cpp [new file with mode: 0644]
modules/widget_dao/dao/property_dao_read_only.cpp [new file with mode: 0644]
modules/widget_dao/dao/webruntime_database.cpp [new file with mode: 0644]
modules/widget_dao/dao/widget_dao.cpp [new file with mode: 0755]
modules/widget_dao/dao/widget_dao_read_only.cpp [new file with mode: 0755]
modules/widget_dao/dao/widget_dao_types.cpp [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/WrtDatabase.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/common_dao_types.h [new file with mode: 0755]
modules/widget_dao/include/dpl/wrt-dao-ro/config_parser_data.h [new file with mode: 0755]
modules/widget_dao/include/dpl/wrt-dao-ro/feature_dao_read_only.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/feature_model.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/global_config.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/path_builder.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/plugin_dao_read_only.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/property_dao_read_only.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/webruntime_database.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/widget_config.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_read_only.h [new file with mode: 0755]
modules/widget_dao/include/dpl/wrt-dao-ro/widget_dao_types.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-ro/wrt_db_types.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-rw/feature_dao.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-rw/plugin_dao.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-rw/property_dao.h [new file with mode: 0644]
modules/widget_dao/include/dpl/wrt-dao-rw/widget_dao.h [new file with mode: 0755]
modules/widget_dao/orm/gen_db_md5.sh [new file with mode: 0755]
modules/widget_dao/orm/orm_generator_wrt.h [new file with mode: 0644]
modules/widget_dao/orm/version_db [new file with mode: 0644]
modules/widget_dao/orm/wrt_db [new file with mode: 0644]
modules/widget_dao/orm/wrt_db_definitions [new file with mode: 0644]
modules/widget_dao/orm/wrt_db_sql_generator.h [new file with mode: 0644]
modules/widget_interface_dao/CMakeLists.txt [new file with mode: 0644]
modules/widget_interface_dao/dao/widget_interface_dao.cpp [new file with mode: 0644]
modules/widget_interface_dao/include/wrt-commons/widget-interface-dao/widget_interface_dao.h [new file with mode: 0644]
modules/widget_interface_dao/orm/orm_generator_widget_interface.h [new file with mode: 0644]
modules/widget_interface_dao/orm/widget_interface_db [new file with mode: 0644]
modules/widget_interface_dao/orm/widget_interface_db_definitions [new file with mode: 0644]
modules/widget_interface_dao/orm/widget_interface_db_sql_generator.h [new file with mode: 0644]
packaging/wrt-commons.spec [new file with mode: 0644]
tests/CMakeLists.txt [new file with mode: 0644]
tests/CMakeUtils.txt [new file with mode: 0644]
tests/common/include/glib_interface.h [new file with mode: 0644]
tests/common/include/loop_control.h [new file with mode: 0644]
tests/common/src/loop_control.cpp [new file with mode: 0644]
tests/core/CMakeLists.txt [new file with mode: 0644]
tests/core/DESCRIPTION [new file with mode: 0644]
tests/core/data/sample.zip [new file with mode: 0644]
tests/core/main.cpp [new file with mode: 0644]
tests/core/test_address.cpp [new file with mode: 0644]
tests/core/test_binary_queue.cpp [new file with mode: 0644]
tests/core/test_bind.cpp [new file with mode: 0644]
tests/core/test_foreach.cpp [new file with mode: 0644]
tests/core/test_log_unhandled_exception.cpp [new file with mode: 0644]
tests/core/test_once.cpp [new file with mode: 0644]
tests/core/test_scope_guard.cpp [new file with mode: 0644]
tests/core/test_scoped_array.cpp [new file with mode: 0644]
tests/core/test_scoped_close.cpp [new file with mode: 0644]
tests/core/test_scoped_dir.cpp [new file with mode: 0644]
tests/core/test_scoped_fclose.cpp [new file with mode: 0644]
tests/core/test_scoped_free.cpp [new file with mode: 0644]
tests/core/test_scoped_ptr.cpp [new file with mode: 0644]
tests/core/test_semaphore.cpp [new file with mode: 0644]
tests/core/test_serialization.cpp [new file with mode: 0644]
tests/core/test_shared_ptr.cpp [new file with mode: 0644]
tests/core/test_single_instance.cpp [new file with mode: 0644]
tests/core/test_static_block.cpp [new file with mode: 0644]
tests/core/test_string.cpp [new file with mode: 0644]
tests/core/test_thread.cpp [new file with mode: 0644]
tests/core/test_type_list.cpp [new file with mode: 0644]
tests/core/test_waitable_handle_watch.cpp [new file with mode: 0644]
tests/core/test_zip_input.cpp [new file with mode: 0644]
tests/dao/CMakeLists.txt [new file with mode: 0644]
tests/dao/README [new file with mode: 0644]
tests/dao/TestCases_CertificateDAO.cpp [new file with mode: 0644]
tests/dao/TestCases_CustomHandlerDAO.cpp [new file with mode: 0644]
tests/dao/TestCases_FeatureDAO.cpp [new file with mode: 0644]
tests/dao/TestCases_PluginDAO.cpp [new file with mode: 0644]
tests/dao/TestCases_PropertyDAO.cpp [new file with mode: 0644]
tests/dao/TestCases_SecurityOriginDAO.cpp [new file with mode: 0644]
tests/dao/TestCases_WidgetDAO.cpp [new file with mode: 0755]
tests/dao/TestCases_WidgetInterfaceDAO.cpp [new file with mode: 0644]
tests/dao/tests_dao.cpp [new file with mode: 0644]
tests/dao/wrt_dao_tests_prepare_db.sh [new file with mode: 0755]
tests/db/CMakeLists.txt [new file with mode: 0644]
tests/db/main.cpp [new file with mode: 0644]
tests/db/orm/CMakeLists.txt [new file with mode: 0644]
tests/db/orm/dpl_orm_test_db [new file with mode: 0644]
tests/db/orm/dpl_orm_test_db_definitions [new file with mode: 0644]
tests/db/orm/dpl_orm_test_db_sql_generator.h [new file with mode: 0644]
tests/db/orm/dpl_orm_test_db_sql_generator.h.gch [new file with mode: 0644]
tests/db/orm/generator_dpl_orm_test.h [new file with mode: 0644]
tests/db/test_orm.cpp [new file with mode: 0644]
tests/db/test_sql_connection.cpp [new file with mode: 0644]
tests/dbus/CMakeLists.txt [new file with mode: 0644]
tests/dbus/data/org.tizen.DBusTestService.service [new file with mode: 0644]
tests/dbus/dbus_test.cpp [new file with mode: 0644]
tests/dbus/dbus_test.h [new file with mode: 0644]
tests/dbus/main.cpp [new file with mode: 0644]
tests/dbus/test_cases.cpp [new file with mode: 0644]
tests/dbus/test_service.cpp [new file with mode: 0644]
tests/event/CMakeLists.txt [new file with mode: 0644]
tests/event/main.cpp [new file with mode: 0644]
tests/event/test_controller.cpp [new file with mode: 0644]
tests/event/test_event_support.cpp [new file with mode: 0644]
tests/event/test_ic_delegate.cpp [new file with mode: 0644]
tests/event/test_property.cpp [new file with mode: 0644]
tests/files_localization/CMakeLists.txt [new file with mode: 0644]
tests/files_localization/files/CMakeLists.txt [new file with mode: 0644]
tests/files_localization/files/icon [new file with mode: 0644]
tests/files_localization/files/icon2 [new file with mode: 0644]
tests/files_localization/files/one [new file with mode: 0644]
tests/files_localization/files/two.html [new file with mode: 0644]
tests/files_localization/test_localization.cpp [new file with mode: 0644]
tests/files_localization/test_suite01.cpp [new file with mode: 0644]
tests/files_localization/wrt_db_localization_prepare.sh [new file with mode: 0644]
tests/i18n/CMakeLists.txt [new file with mode: 0644]
tests/i18n/main.cpp [new file with mode: 0644]
tests/i18n/test_i18n_dao_read_only.cpp [new file with mode: 0644]
tests/localizationTagsProvider/CMakeLists.txt [new file with mode: 0644]
tests/localizationTagsProvider/Localization_testcases.cpp [new file with mode: 0644]
tests/localizationTagsProvider/README [new file with mode: 0644]
tests/localizationTagsProvider/tests_miscunit.cpp [new file with mode: 0644]
tests/test/CMakeLists.txt [new file with mode: 0644]
tests/test/main.cpp [new file with mode: 0644]
tests/test/runner_child.cpp [new file with mode: 0644]
tests/test/runner_multiprocess.cpp [new file with mode: 0644]
tests/test/test_abstract_input_reader.cpp [new file with mode: 0644]
tests/test/test_process_pipe.cpp [new file with mode: 0644]
tests/test/test_value_separated_reader.cpp [new file with mode: 0644]
tests/unused/test_caller.cpp [new file with mode: 0644]
tests/unused/test_crypto_hash.cpp [new file with mode: 0644]
tests/unused/test_message_queue.cpp [new file with mode: 0644]
tests/unused/test_shm.cpp [new file with mode: 0644]
tests/unused/test_sql_connection.cpp [new file with mode: 0644]
tests/unused/test_task.cpp [new file with mode: 0644]
tests/utils/CMakeLists.txt [new file with mode: 0644]
tests/utils/bash_utils.cpp [new file with mode: 0644]
tests/utils/main.cpp [new file with mode: 0644]
tests/utils/path_tests.cpp [new file with mode: 0644]
tests/utils/widget_version.cpp [new file with mode: 0644]
tests/utils/wrt_utility.cpp [new file with mode: 0644]
uncrustify.cfg [new file with mode: 0644]
uncrustify.sh [new file with mode: 0755]
wrt-commons [new file with mode: 0644]
wrt-commons.manifest [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100755 (executable)
index 0000000..4c72b9c
--- /dev/null
@@ -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 (file)
index 0000000..ffc39e1
--- /dev/null
@@ -0,0 +1,203 @@
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES 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)
+ADD_DEFINITIONS(-DLOG_TAG="WRT-COMMONS")
+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 (file)
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 (file)
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 (file)
index 0000000..b94d51f
--- /dev/null
@@ -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 (executable)
index 0000000..e893640
--- /dev/null
@@ -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 (file)
index 0000000..903dc95
--- /dev/null
@@ -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 (file)
index 0000000..cdc17cf
--- /dev/null
@@ -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        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
+  capi-appfw-application
+  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 (file)
index 0000000..f7f1581
--- /dev/null
@@ -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 (file)
index 0000000..6d2a882
--- /dev/null
@@ -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 (file)
index 0000000..cacc560
--- /dev/null
@@ -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 (file)
index 0000000..7cda187
--- /dev/null
@@ -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 (file)
index 0000000..4cd2737
--- /dev/null
@@ -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 (file)
index 0000000..282e55b
--- /dev/null
@@ -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 (file)
index 0000000..866bb0f
--- /dev/null
@@ -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 (file)
index 0000000..d274572
--- /dev/null
@@ -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 (file)
index 0000000..73f2c03
--- /dev/null
@@ -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 (file)
index 0000000..46e13f1
--- /dev/null
@@ -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        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}
+)
+
+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 (file)
index 0000000..d4befbe
--- /dev/null
@@ -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 (file)
index 0000000..20ef24c
--- /dev/null
@@ -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 (file)
index 0000000..270630b
--- /dev/null
@@ -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 (file)
index 0000000..497f98d
--- /dev/null
@@ -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 (file)
index 0000000..7f18689
--- /dev/null
@@ -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 (file)
index 0000000..b585c37
--- /dev/null
@@ -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 (file)
index 0000000..d857bbe
--- /dev/null
@@ -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 (file)
index 0000000..7e6d0d3
--- /dev/null
@@ -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 (file)
index 0000000..2ab81cb
--- /dev/null
@@ -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 (file)
index 0000000..b5b6e47
--- /dev/null
@@ -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 (file)
index 0000000..1e1409a
--- /dev/null
@@ -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 (file)
index 0000000..8a1345e
--- /dev/null
@@ -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 (file)
index 0000000..b35b9b4
--- /dev/null
@@ -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 (file)
index 0000000..6c6c573
--- /dev/null
@@ -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 (file)
index 0000000..056ae09
--- /dev/null
@@ -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 (file)
index 0000000..14bc1aa
--- /dev/null
@@ -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 (file)
index 0000000..8e1d4c9
--- /dev/null
@@ -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 (file)
index 0000000..f52c106
--- /dev/null
@@ -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 (file)
index 0000000..d2d112b
--- /dev/null
@@ -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 (file)
index 0000000..c71e58d
--- /dev/null
@@ -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 (file)
index 0000000..d132545
--- /dev/null
@@ -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 (file)
index 0000000..348b178
--- /dev/null
@@ -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 (executable)
index 0000000..13eb011
--- /dev/null
@@ -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 (file)
index 0000000..c3f01bd
--- /dev/null
@@ -0,0 +1 @@
+Documentation
diff --git a/doc/doxyfile b/doc/doxyfile
new file mode 100644 (file)
index 0000000..f058b7a
--- /dev/null
@@ -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 <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> 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 <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> 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 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+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 (file)
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 (file)
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 (file)
index 0000000..f3436e6
--- /dev/null
@@ -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 (file)
index 0000000..bf6eac9
--- /dev/null
@@ -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 (executable)
index 0000000..d77048b
--- /dev/null
@@ -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 (executable)
index 0000000..6d578c7
--- /dev/null
@@ -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 (file)
index 0000000..82e583f
--- /dev/null
@@ -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 (file)
index 0000000..db99a6d
--- /dev/null
@@ -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 (file)
index 0000000..5fb9fee
--- /dev/null
@@ -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 (file)
index 0000000..063b6af
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/binary_queue.h>
+#include <dpl/exception.h>
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+
+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 (file)
index 0000000..ace88df
--- /dev/null
@@ -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 (file)
index 0000000..5fa9484
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/file_input.h>
+#include <dpl/file_output.h>
+#include <dpl/copy.h>
+#include <iostream>
+#include <cstdlib>
+
+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<size_t>(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 (file)
index 0000000..e0b0598
--- /dev/null
@@ -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 (file)
index 0000000..791b971
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/crypto_hash.h>
+#include <iostream>
+#include <string>
+
+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 100755 (executable)
index 0000000..48add08
--- /dev/null
@@ -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 (file)
index 0000000..878febf
--- /dev/null
@@ -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 <stddef.h>
+#include <iostream>
+#include <string>
+
+#include <dpl/dbus/dbus_client.h>
+
+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 100755 (executable)
index 0000000..4562355
--- /dev/null
@@ -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 (file)
index 0000000..84e665d
--- /dev/null
@@ -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 <stddef.h>
+#include <memory>
+#include <iostream>
+#include <gio/gio.h>
+#include <dpl/event_listener.h>
+#include <dpl/log/log.h>
+#include <dpl/thread.h>
+#include <dpl/dbus/server.h>
+#include <dpl/dbus/connection.h>
+
+std::string xml = 
+"<node>"
+"  <interface name='org.tizen.EchoInterface'>"
+"    <method name='echo'>"
+"      <arg type='s' name='input' direction='in'/>"
+"      <arg type='s' name='output' direction='out'/>"
+"    </method>"
+"  </interface>"
+"  <interface name='org.tizen.QuitInterface'>"
+"    <method name='quit'>"
+"    </method>"
+"  </interface>"
+"</node>";
+
+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<DPL::DBus::ServerEvents::NewConnectionEvent>
+{
+protected:
+    void OnEventReceived(const DPL::DBus::ServerEvents::NewConnectionEvent& event)
+    {
+        m_connection = event.GetArg0();
+
+        auto quitInterface = g_interfaces.at(1);
+        quitInterface->setDispatcher(std::make_shared<DBusDispatcher>());
+        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<DBusDispatcher>());
+
+  auto echoObject = DPL::DBus::Object::create("/object/echo", echoInterface);
+
+  echoConnection->registerObject(echoObject);
+
+  echoConnection->registerService("org.tizen.EchoService");
+
+  // --------------- quit
+  std::unique_ptr<NewConnectionListener> 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 (file)
index 0000000..0778da7
--- /dev/null
@@ -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 (file)
index 0000000..bab1069
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/unix_socket_rpc_client.h>
+#include <dpl/unix_socket_rpc_server.h>
+#include <dpl/unix_socket_rpc_connection.h>
+#include <dpl/fake_rpc_connection.h>
+#include <memory>
+#include <dpl/application.h>
+#include <dpl/controller.h>
+#include <dpl/thread.h>
+#include <dpl/log/log.h>
+#include <string>
+
+// 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<AsyncCallEvent>,
+      private DPL::EventListener<ConnectionEstablishedEvent>
+{
+private:
+    DPL::UnixSocketRPCClient m_rpcUnixClient;
+    DPL::FakeRpcClient m_rpcFakeClient;
+    int m_connections;
+    int m_sentData;
+    int m_receivedData;
+
+    std::unique_ptr<DPL::AbstractRPCConnection> m_rpcUnixConnection;
+    std::unique_ptr<DPL::AbstractRPCConnection> 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<DPL::FakeRpcConnection *>(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<AsyncCallEvent>::AddListener(this);
+        }
+        else{
+            ++m_connections;
+            LogDebug("CLIENT: Acquiring new unix connection");
+            m_rpcUnixConnection.reset(event.GetArg1());
+            m_rpcUnixConnection->DPL::EventSupport<AsyncCallEvent>::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<ConnectionEstablishedEvent>::AddListener(this);
+        m_rpcFakeClient.DPL::EventSupport<ConnectionEstablishedEvent>::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<AsyncCallEvent>::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<AsyncCallEvent>::RemoveListener(this);
+            m_rpcFakeConnection.reset();
+        }
+
+        // Detach RPC client listener
+        LogDebug("CLIENT: Detaching connection established event");
+        m_rpcUnixClient.DPL::EventSupport<ConnectionEstablishedEvent>::RemoveListener(this);
+        m_rpcFakeClient.DPL::EventSupport<ConnectionEstablishedEvent>::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<DPL::TypeListDecl<QuitEvent,
+                                                CloseThreadEvent>::Type>,
+      private DPL::EventListener<AsyncCallEvent>,
+      private DPL::EventListener<ConnectionEstablishedEvent>
+{
+private:
+    DPL::UnixSocketRPCServer m_rpcUnixServer;
+    DPL::FakeRpcServer m_rpcFakeServer;
+
+    std::unique_ptr<DPL::AbstractRPCConnection> m_rpcUnixConnection;
+    std::unique_ptr<DPL::AbstractRPCConnection> 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<AsyncCallEvent>::RemoveListener(this);
+            m_rpcUnixConnection.reset();
+        }
+
+        if (m_rpcFakeConnection.get()) {
+            m_rpcFakeConnection->DPL::EventSupport<AsyncCallEvent>::RemoveListener(this);
+            m_rpcFakeConnection.reset();
+        }
+
+        LogDebug("SERVER: Closing Server");
+        m_rpcUnixServer.CloseAll();
+        m_rpcFakeServer.CloseAll();//not needed
+        m_rpcUnixServer.DPL::EventSupport<ConnectionEstablishedEvent>::RemoveListener(this);
+        m_rpcFakeServer.DPL::EventSupport<ConnectionEstablishedEvent>::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<DPL::FakeRpcConnection *>(event.GetArg1())){
+            LogDebug("SERVER: Acquiring Fake RPC connection");
+            m_rpcFakeConnection.reset(event.GetArg1());
+            m_rpcFakeConnection->DPL::EventSupport<AsyncCallEvent>::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<AsyncCallEvent>::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<ConnectionEstablishedEvent>::AddListener(this);
+        m_rpcFakeServer.DPL::EventSupport<ConnectionEstablishedEvent>::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<CloseThreadEvent>::PostTimedEvent(CloseThreadEvent(), 2);
+        DPL::ControllerEventHandler<QuitEvent>::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 (file)
index 0000000..b5d1017
--- /dev/null
@@ -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 (file)
index 0000000..1fca0df
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/tcp_socket_rpc_client.h>
+#include <dpl/tcp_socket_rpc_connection.h>
+#include <dpl/application.h>
+#include <dpl/log/log.h>
+
+class MetronomeClientApplication
+    : public DPL::Application,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::AsyncCallEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>
+{
+private:
+    DPL::TcpSocketRPCClient m_rpcClient;
+    std::unique_ptr<DPL::AbstractRPCConnection> 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<DPL::AbstractRPCConnectionEvents::AsyncCallEvent>::AddListener(this);
+        m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::AddListener(this);
+        m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::AddListener(this);
+    }
+
+public:
+    MetronomeClientApplication(int argc, char **argv)
+        : Application(argc, argv, "rpc")
+    {
+        // Attach RPC server listeners
+        m_rpcClient.DPL::EventSupport<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::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<DPL::AbstractRPCConnectionEvents::AsyncCallEvent>::RemoveListener(this);
+            m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::RemoveListener(this);
+            m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::RemoveListener(this);
+            m_rpcConnection.reset();
+        }
+
+        // Close RPC server
+        m_rpcClient.CloseAll();
+
+        // Detach RPC server listener
+        m_rpcClient.DPL::EventSupport<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::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 (file)
index 0000000..cc0ad0a
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/tcp_socket_rpc_server.h>
+#include <dpl/tcp_socket_rpc_connection.h>
+#include <dpl/controller.h>
+#include <dpl/application.h>
+#include <dpl/type_list.h>
+#include <dpl/log/log.h>
+#include <algorithm>
+#include <list>
+#include <dpl/assert.h>
+
+// 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<DPL::TypeListDecl<SignalEvent,
+                                                DeleteConnectionEvent>::Type>,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>
+{
+private:
+    DPL::TcpSocketRPCServer m_rpcServer;
+
+    typedef std::list<DPL::AbstractRPCConnection *> 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<SignalEvent>::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<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::RemoveListener(this);
+        connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::RemoveListener(this);
+
+        // Delete connection
+        DPL::ControllerEventHandler<DeleteConnectionEvent>::PostEvent(DeleteConnectionEvent(connection));
+    }
+
+    void AddConnection(DPL::AbstractRPCConnection *connection)
+    {
+        // Add connection
+        m_connections.push_back(connection);
+
+        // Attach event listeners
+        connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::AddListener(this);
+        connection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::AddListener(this);
+    }
+
+    virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent &event)
+    {
+        (void)event;
+
+        LogDebug("Connection closed");
+
+        // Remove connection from list
+        RemoveConnection(static_cast<DPL::AbstractRPCConnection *>(event.GetSender()));
+    }
+
+    virtual void OnEventReceived(const DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent &event)
+    {
+        (void)event;
+
+        LogDebug("Connection broken");
+
+        // Remove connection from list
+        RemoveConnection(static_cast<DPL::AbstractRPCConnection *>(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<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::AddListener(this);
+
+        // Inherit calling context
+        Touch();
+
+        // Open RPC server
+        m_rpcServer.Open(12345);
+
+        // Start heart beat
+        DPL::ControllerEventHandler<SignalEvent>::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<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::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 (file)
index 0000000..d9c7d57
--- /dev/null
@@ -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 (file)
index 0000000..6991edb
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/unix_socket_rpc_client.h>
+#include <dpl/unix_socket_rpc_server.h>
+#include <dpl/unix_socket_rpc_connection.h>
+#include <memory>
+#include <dpl/application.h>
+#include <dpl/controller.h>
+#include <dpl/thread.h>
+#include <dpl/log/log.h>
+#include <string>
+
+static const char *RPC_NAME = "/tmp/unix_socket_rpc";
+
+class MyThread
+    : public DPL::Thread,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::AsyncCallEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>
+{
+private:
+    DPL::UnixSocketRPCClient m_rpcClient;
+    std::unique_ptr<DPL::AbstractRPCConnection> 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<DPL::AbstractRPCConnectionEvents::AsyncCallEvent>::AddListener(this);
+        m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::AddListener(this);
+        m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::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<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::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<DPL::AbstractRPCConnectionEvents::AsyncCallEvent>::RemoveListener(this);
+            m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::RemoveListener(this);
+            m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::RemoveListener(this);
+
+            LogDebug("CLIENT: Resetting connection");
+            m_rpcConnection.reset();
+        }
+
+        // Detach RPC client listener
+        LogDebug("CLIENT: Detaching connection established event");
+        m_rpcClient.DPL::EventSupport<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::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<DPL::TypeListDecl<QuitEvent,
+                                                CloseThreadEvent>::Type>,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::AsyncCallEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>,
+      private DPL::EventListener<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>
+{
+private:
+    DPL::UnixSocketRPCServer m_rpcServer;
+    std::unique_ptr<DPL::AbstractRPCConnection> 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<DPL::AbstractRPCConnectionEvents::AsyncCallEvent>::RemoveListener(this);
+            m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::RemoveListener(this);
+            m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::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<DPL::AbstractRPCConnectionEvents::AsyncCallEvent>::AddListener(this);
+        m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent>::AddListener(this);
+        m_rpcConnection->DPL::EventSupport<DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent>::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<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::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<CloseThreadEvent>::PostTimedEvent(CloseThreadEvent(), 2);
+        DPL::ControllerEventHandler<QuitEvent>::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<DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent>::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 (file)
index 0000000..42020ec
--- /dev/null
@@ -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 (file)
index 0000000..2ed9fab
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/log/log.h>
+
+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 (file)
index 0000000..3c29cc6
--- /dev/null
@@ -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 (file)
index 0000000..038594b
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/single_instance.h>
+#include <iostream>
+
+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 (file)
index 0000000..9fe5009
--- /dev/null
@@ -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 (file)
index 0000000..fc42632
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/unix_socket.h>
+#include <dpl/abstract_socket.h>
+#include <dpl/application.h>
+#include <dpl/controller.h>
+#include <dpl/generic_event.h>
+#include <dpl/thread.h>
+#include <dpl/log/log.h>
+#include <string>
+#include <dpl/assert.h>
+
+namespace // anonymous
+{
+static const char *SOCKET_NAME = "/tmp/unix_sock";
+} // namespace anonymous
+
+class MyThread
+    : public DPL::Thread,
+      private DPL::EventListener<DPL::AbstractSocketEvents::AcceptEvent>
+{
+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<DPL::UnixSocket *>(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<DPL::AbstractSocketEvents::AcceptEvent>::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<DPL::AbstractSocketEvents::AcceptEvent>::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<DPL::TypeListDecl<QuitEvent>::Type>,
+      private DPL::EventListener<DPL::AbstractSocketEvents::ConnectedEvent>
+{
+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<DPL::AbstractSocketEvents::ConnectedEvent>::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<QuitEvent>::PostTimedEvent(QuitEvent(), 2);
+    }
+
+    virtual ~MyApplication()
+    {
+        // Remove listeners
+        sock.DPL::EventSupport<DPL::AbstractSocketEvents::ConnectedEvent>::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 (file)
index 0000000..a6550fc
--- /dev/null
@@ -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 (file)
index 0000000..57141ca
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/tcp_socket.h>
+#include <dpl/abstract_socket.h>
+#include <dpl/application.h>
+#include <dpl/generic_event.h>
+#include <dpl/binary_queue.h>
+#include <dpl/scoped_array.h>
+#include <dpl/log/log.h>
+#include <string>
+#include <dpl/assert.h>
+
+class MyApplication
+    : public DPL::Application,
+      private DPL::EventListener<DPL::AbstractSocketEvents::ConnectedEvent>,
+      private DPL::EventListener<DPL::AbstractSocketEvents::ReadEvent>
+{
+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<char> 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<DPL::AbstractSocketEvents::ConnectedEvent>::AddListener(this);
+        m_socket.DPL::EventSupport<DPL::AbstractSocketEvents::ReadEvent>::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<DPL::AbstractSocketEvents::ConnectedEvent>::RemoveListener(this);
+        m_socket.DPL::EventSupport<DPL::AbstractSocketEvents::ReadEvent>::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 (file)
index 0000000..cb60fb0
--- /dev/null
@@ -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 (file)
index 0000000..f3d8e80
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/generic_event.h>
+#include <dpl/application.h>
+#include <dpl/controller.h>
+#include <dpl/type_list.h>
+#include <dpl/thread.h>
+#include <dpl/log/log.h>
+#include <string>
+
+DECLARE_GENERIC_EVENT_0(FirstEvent)
+DECLARE_GENERIC_EVENT_0(SecondEvent)
+
+class ControllerInThread
+    : public DPL::Controller<DPL::TypeListDecl<FirstEvent,
+                                               SecondEvent>::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<DPL::TypeListDecl<QuitEvent>::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<SecondEvent>::PostTimedEvent(SecondEvent(), 3);
+        m_controllerInThread.DPL::ControllerEventHandler<FirstEvent>::PostTimedEvent(FirstEvent(), 2);
+
+        // Emit framework timed quit event
+        DPL::ControllerEventHandler<QuitEvent>::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 (file)
index 0000000..e3038e1
--- /dev/null
@@ -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 (executable)
index 0000000..60d076c
--- /dev/null
@@ -0,0 +1,58 @@
+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
+    dlog
+    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 (file)
index 0000000..0d2138f
--- /dev/null
@@ -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 <wrt-commons/certificate-dao/certificate_dao.h>
+#include <wrt-commons/certificate-dao/certificate_database.h>
+#include <wrt-commons/certificate-dao/certificate_dao_types.h>
+#include <orm_generator_certificate.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <dpl/wrt-dao-ro/widget_config.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+#include <sys/stat.h>
+#include <fstream>
+/* GCC versions 4.7 had changes to the C++ standard. It
+ * no longer includes <unistd.h> to remove namespace pollution.
+ */
+#include <unistd.h>
+
+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<CertificateInfo::Row> 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<CertificateInfo::certificate>(certificateData.certificate));
+        CertificateInfo::Select::RowList rows = select->GetRowList();
+
+        if (rows.empty()) {
+            return RESULT_UNKNOWN;
+        }
+        CertificateInfo::Row row = rows.front();
+        return static_cast<Result>(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<CertificateInfo::certificate>(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<CertificateInfo::result>(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 (executable)
index 0000000..35e8a58
--- /dev/null
@@ -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 <wrt-commons/certificate-dao/certificate_dao_types.h>
+#include <dpl/log/log.h>
+
+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 (executable)
index 0000000..4392e0c
--- /dev/null
@@ -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 <wrt-commons/certificate-dao/certificate_database.h>
+
+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 (file)
index 0000000..26e981b
--- /dev/null
@@ -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 <dpl/db/thread_database_support.h>
+#include <wrt-commons/certificate-dao/certificate_dao_types.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+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<CertificateDAO> 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 (executable)
index 0000000..f059f4c
--- /dev/null
@@ -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 <list>
+#include <memory>
+#include <dpl/string.h>
+
+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<CertificateData> CertificateDataPtr;
+typedef std::list<CertificateDataPtr> 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 (executable)
index 0000000..f0ee954
--- /dev/null
@@ -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 <dpl/thread.h>
+#include <dpl/mutex.h>
+
+extern DPL::Mutex g_certificateDBQueriesMutex;
+
+#define CERTIFICATE_DB_INTERNAL(tlsCommand, InternalType, interface)            \
+    static DPL::ThreadLocalVariable<InternalType> *tlsCommand##Ptr = NULL; \
+    {                                                                        \
+        DPL::Mutex::ScopedLock lock(&g_certificateDBQueriesMutex);              \
+        if (!tlsCommand##Ptr) {                                            \
+            static DPL::ThreadLocalVariable<InternalType> tmp;               \
+            tlsCommand##Ptr = &tmp;                                        \
+        }                                                                    \
+    }                                                                        \
+    DPL::ThreadLocalVariable<InternalType> &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 (executable)
index 0000000..2dbe366
--- /dev/null
@@ -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 (file)
index 0000000..6cfdc11
--- /dev/null
@@ -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 (executable)
index 0000000..07c1816
--- /dev/null
@@ -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 <dpl/db/orm_macros.h>
+
+#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 (executable)
index 0000000..6822708
--- /dev/null
@@ -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 <dpl/db/orm_generator.h>
+#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 (file)
index 0000000..1369c40
--- /dev/null
@@ -0,0 +1 @@
+Main library code
diff --git a/modules/core/config.cmake b/modules/core/config.cmake
new file mode 100644 (file)
index 0000000..13f83d1
--- /dev/null
@@ -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 (file)
index 0000000..6dfd446
--- /dev/null
@@ -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 (file)
index 0000000..8c0e16a
--- /dev/null
@@ -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 <dpl/exception.h>
+#include <memory>
+
+namespace DPL {
+class BinaryQueue;
+typedef std::auto_ptr<BinaryQueue> 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 (file)
index 0000000..153d5c4
--- /dev/null
@@ -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 <dpl/abstract_input.h>
+#include <dpl/abstract_output.h>
+
+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 (file)
index 0000000..56c86fb
--- /dev/null
@@ -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 <dpl/exception.h>
+#include <memory>
+
+namespace DPL {
+class BinaryQueue;
+typedef std::auto_ptr<BinaryQueue> 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 (file)
index 0000000..9d957d6
--- /dev/null
@@ -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 <dpl/waitable_handle.h>
+#include <dpl/abstract_input.h>
+
+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 (file)
index 0000000..43efaee
--- /dev/null
@@ -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 <dpl/abstract_waitable_input.h>
+#include <dpl/waitable_event.h>
+#include <dpl/abstract_input.h>
+
+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 (file)
index 0000000..e858f51
--- /dev/null
@@ -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 <dpl/abstract_waitable_input.h>
+#include <dpl/abstract_waitable_output.h>
+
+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 (file)
index 0000000..a0322d0
--- /dev/null
@@ -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 <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/abstract_waitable_output_adapter.h>
+#include <dpl/abstract_input_output.h>
+
+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 (file)
index 0000000..abcc3f8
--- /dev/null
@@ -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 <dpl/abstract_output.h>
+#include <dpl/waitable_handle.h>
+
+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 (file)
index 0000000..9e40bc4
--- /dev/null
@@ -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 <dpl/abstract_waitable_output.h>
+#include <dpl/waitable_event.h>
+#include <dpl/abstract_output.h>
+
+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 (file)
index 0000000..05893f9
--- /dev/null
@@ -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 <dpl/exception.h>
+#include <string>
+
+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 (file)
index 0000000..4400545
--- /dev/null
@@ -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 (file)
index 0000000..188d7ac
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES 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 <dpl/exception.h>
+#include <dpl/framework_efl.h>
+#include <dpl/framework_appcore.h>
+#include <dpl/atomic.h>
+#include <string>
+
+namespace DPL {
+class Application
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, TooManyInstances)
+        DECLARE_EXCEPTION_TYPE(Base, FrameworkError)
+    };
+
+  protected:
+    int m_argc;
+    char **m_argv;
+    std::string m_applicationName;
+
+    bool m_mainWindowVisible;
+
+    static bool app_create(void *data);
+    static void app_terminate(void *data);
+    static void app_pause(void *data);
+    static void app_resume(void *data);
+    static void app_control(app_control_h app_control, void *data);
+
+    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 (file)
index 0000000..fc1be53
--- /dev/null
@@ -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 <bits/c++0x_warning.h>
+#else
+
+#include <tuple>
+#include <utility>
+
+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<ExtraArgsInsertPolicy>
+struct _ApplyDispatchByPolicy;
+
+template<typename Result = void,
+         ExtraArgsInsertPolicy insertPolicy = ExtraArgsInsertPolicy::Append,
+         typename Operation,
+         typename ... ArgsT,
+         typename ... ArgsE>
+Result Apply(Operation op,
+             const std::tuple<ArgsT ...>& t,
+             ArgsE && ... extra)
+{
+    return _ApplyDispatchByPolicy<insertPolicy>::
+               template Apply<Result>(op, t, std::forward<ArgsE>(extra) ...);
+}
+
+template<size_t N, size_t M>
+struct _ApplyTuple
+{
+    template<typename Result,
+             typename Operation,
+             typename ... ArgsT1,
+             typename ... ArgsT2,
+             typename ... Args>
+    static Result Apply(Operation op,
+                        const std::tuple<ArgsT1 ...>& t1,
+                        const std::tuple<ArgsT2 ...>& t2,
+                        Args && ... args)
+    {
+        return _ApplyTuple<N - 1, M>::
+                   template Apply<Result>(op,
+                                          t1,
+                                          t2,
+                                          std::get<N - 1>(t1),
+                                          std::forward<Args>(args) ...);
+    }
+};
+
+template<size_t M>
+struct _ApplyTuple<0, M>
+{
+    template<typename Result,
+             typename Operation,
+             typename ... ArgsT1,
+             typename ... ArgsT2,
+             typename ... Args>
+    static Result Apply(Operation op,
+                        const std::tuple<ArgsT1 ...>& t1,
+                        const std::tuple<ArgsT2 ...>& t2,
+                        Args && ... args)
+    {
+        return _ApplyTuple<0, M - 1>::
+                   template Apply<Result>(op,
+                                          t1,
+                                          t2,
+                                          std::get<M - 1>(t2),
+                                          std::forward<Args>(args) ...);
+    }
+};
+
+template<>
+struct _ApplyTuple<0, 0>
+{
+    template<typename Result,
+             typename Operation,
+             typename ... ArgsT1,
+             typename ... ArgsT2,
+             typename ... Args>
+    static Result Apply(Operation op,
+                        const std::tuple<ArgsT1 ...>&,
+                        const std::tuple<ArgsT2 ...>&,
+                        Args && ... args)
+    {
+        return op(std::forward<Args>(args) ...);
+    }
+};
+
+template<size_t N>
+struct _ApplyArgs
+{
+    template<typename Result,
+             typename Operation,
+             typename ... ArgsT,
+             typename ... Args>
+    static Result Apply(Operation op,
+                        const std::tuple<ArgsT ...>& t,
+                        Args && ... args)
+    {
+        return _ApplyArgs<N - 1>::
+                   template Apply<Result>(op,
+                                          t,
+                                          std::get<N - 1>(t),
+                                          std::forward<Args>(args) ...);
+    }
+};
+
+template<>
+struct _ApplyArgs<0>
+{
+    template<typename Result,
+             typename Operation,
+             typename ... ArgsT,
+             typename ... Args>
+    static Result Apply(Operation op,
+                        const std::tuple<ArgsT ...>&,
+                        Args && ... args)
+    {
+        return op(std::forward<Args>(args) ...);
+    }
+};
+
+template<>
+struct _ApplyDispatchByPolicy<ExtraArgsInsertPolicy::Append>
+{
+    template<typename Result,
+             typename Operation,
+             typename ... ArgsT,
+             typename ... ArgsE>
+    static Result Apply(Operation op,
+                        const std::tuple<ArgsT ...>& t,
+                        ArgsE && ... extra)
+    {
+        return _ApplyArgs<sizeof ... (ArgsT)>::
+                   template Apply<Result>(op,
+                                          t,
+                                          std::forward<ArgsE>(extra) ...);
+    }
+};
+
+template<>
+struct _ApplyDispatchByPolicy<ExtraArgsInsertPolicy::Prepend>
+{
+    template<typename Result,
+             typename Operation,
+             typename ... ArgsT,
+             typename ... ArgsE>
+    static Result Apply(Operation op,
+                        const std::tuple<ArgsT ...>& t,
+                        ArgsE && ... extra)
+    {
+        return _ApplyTuple<sizeof ... (ArgsT), sizeof ... (ArgsE)>::
+                   template Apply<Result>(op,
+                                          t,
+                                          std::make_tuple(std::forward<ArgsE>(
+                                                              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 (file)
index 0000000..abdb481
--- /dev/null
@@ -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 (file)
index 0000000..50c4a1a
--- /dev/null
@@ -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 <glib.h>
+
+namespace DPL {
+class Atomic
+{
+  public:
+    typedef gint ValueType;
+
+  private:
+    volatile ValueType m_value;
+
+  public:
+    Atomic(ValueType value = static_cast<ValueType>(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 (file)
index 0000000..0813892
--- /dev/null
@@ -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 (file)
index 0000000..f4fa278
--- /dev/null
@@ -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 <dpl/abstract_input_output.h>
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <memory>
+#include <list>
+
+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<Bucket *> 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<BinaryQueue> 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 (file)
index 0000000..190319b
--- /dev/null
@@ -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<ResultType(Args...)> delegate =
+ *      DPL::Bind(&ObjectType::MethodName, &object);
+ */
+
+#ifndef DPL_BIND_H_
+#define DPL_BIND_H_
+
+#include <functional>
+
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/arithmetic/add.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+
+namespace DPL {
+namespace detail {
+template<size_t>
+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<count>                                           \
+{                                                                              \
+    template<typename Result, typename Type, typename ...Args>                 \
+    static std::function<Result(Args...)>                                      \
+    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<typename Result, typename Type, typename ...Args>
+std::function<Result(Args...)> Bind(Result(Type::*method)(Args...),
+                                    Type* object)
+{
+    return detail::PlaceholdersBindHelper<sizeof...(Args)>::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 (file)
index 0000000..a432df3
--- /dev/null
@@ -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 <dpl/availability.h>
+
+#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 (file)
index 0000000..eb2988f
--- /dev/null
@@ -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 <cstring>
+#include <string>
+#include <ostream>
+#include <algorithm>
+#include <dpl/exception.h>
+
+namespace DPL {
+typedef std::char_traits<wchar_t> 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 (file)
index 0000000..c7cfd53
--- /dev/null
@@ -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 (file)
index 0000000..e796a61
--- /dev/null
@@ -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 <dpl/abstract_waitable_input.h>
+#include <dpl/abstract_waitable_output.h>
+#include <dpl/exception.h>
+
+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 (file)
index 0000000..0a0fb3a
--- /dev/null
@@ -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 <dpl/shared_ptr.h>
+#include <dpl/noncopyable.h>
+#include <dpl/assert.h>
+
+namespace DPL {
+template<typename Class>
+class EnableSharedFromThis : private Noncopyable
+{
+  private:
+    // A weak pointer to shared counter
+    SharedCounter *m_counter;
+    Class *m_ptr;
+
+  public:
+    DPL::SharedPtr<Class> SharedFromThis()
+    {
+        Assert(m_counter != NULL && "Pointer is not shared!");
+        return SharedPtr<Class>(m_counter, m_ptr);
+    }
+
+    DPL::SharedPtr<const Class> SharedFromThis() const
+    {
+        Assert(m_counter != NULL && "Pointer is not shared!");
+        return SharedPtr<Class>(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 (file)
index 0000000..446dbc9
--- /dev/null
@@ -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 <dpl/exception.h>
+#include <string>
+#include <cerrno>
+
+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 (file)
index 0000000..cdbdc53
--- /dev/null
@@ -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 <string>
+#include <cstring>
+#include <cstdio>
+#include <exception>
+#include <cstdlib>
+#include <sstream>
+
+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() ? "<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() ? "<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 (file)
index 0000000..3adcf21
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <dpl/abstract_waitable_input.h>
+
+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 (file)
index 0000000..90be8cd
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <dpl/abstract_waitable_output.h>
+
+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 (file)
index 0000000..bbe477a
--- /dev/null
@@ -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 <dpl/preprocessor.h>
+
+namespace DPL {
+namespace Private {
+/*
+ * Used to detect type of valid reference to value object.
+ */
+template <typename T>
+T& ValueReference(T& t)
+{
+    return(t);
+}
+
+template <typename T>
+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 (file)
index 0000000..d076ddc
--- /dev/null
@@ -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 <app.h>
diff --git a/modules/core/include/dpl/framework_efl.h b/modules/core/include/dpl/framework_efl.h
new file mode 100644 (file)
index 0000000..6246587
--- /dev/null
@@ -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 <Ecore.h>
+#include <Elementary.h>
+#include <Ecore_X.h>
diff --git a/modules/core/include/dpl/framework_vconf.h b/modules/core/include/dpl/framework_vconf.h
new file mode 100644 (file)
index 0000000..8de9b31
--- /dev/null
@@ -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 <vconf.h>
+#include <vconf-keys.h>
diff --git a/modules/core/include/dpl/generic_event.h b/modules/core/include/dpl/generic_event.h
new file mode 100644 (file)
index 0000000..b20d913
--- /dev/null
@@ -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<typename Arg0Type>
+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<typename Arg0Type, typename Arg1Type>
+class GenericEvent2 :
+    public GenericEvent1<Arg0Type>
+{
+  public:
+    typedef Arg0Type Arg0;
+    typedef Arg1Type Arg1;
+
+  protected:
+    Arg1 m_arg1;
+
+  public:
+    explicit GenericEvent2(const EventSender &sender) :
+        GenericEvent1<Arg0Type>(sender)
+    {}
+
+    GenericEvent2(Arg0 arg0, Arg1 arg1, const EventSender &sender) :
+        GenericEvent1<Arg0Type>(arg0, sender),
+        m_arg1(arg1)
+    {}
+
+    virtual ~GenericEvent2()
+    {}
+
+    Arg1 GetArg1() const
+    {
+        return m_arg1;
+    }
+};
+
+template<typename Arg0Type, typename Arg1Type, typename Arg2Type>
+class GenericEvent3 :
+    public GenericEvent2<Arg0Type, Arg1Type>
+{
+  public:
+    typedef Arg0Type Arg0;
+    typedef Arg1Type Arg1;
+    typedef Arg2Type Arg2;
+
+  protected:
+    Arg2 m_arg2;
+
+  public:
+    explicit GenericEvent3(const EventSender &sender) :
+        GenericEvent2<Arg0Type, Arg1Type>(sender)
+    {}
+
+    GenericEvent3(Arg0 arg0, Arg1 arg1, Arg2 arg2, const EventSender &sender) :
+        GenericEvent2<Arg0Type, Arg1Type>(arg0, arg1, sender),
+        m_arg2(arg2)
+    {}
+
+    virtual ~GenericEvent3()
+    {}
+
+    Arg2 GetArg2() const
+    {
+        return m_arg2;
+    }
+};
+
+template<typename Arg0Type, typename Arg1Type, typename Arg2Type,
+         typename Arg3Type>
+class GenericEvent4 :
+    public GenericEvent3<Arg0Type, Arg1Type, Arg2Type>
+{
+  public:
+    typedef Arg0Type Arg0;
+    typedef Arg1Type Arg1;
+    typedef Arg2Type Arg2;
+    typedef Arg3Type Arg3;
+
+  protected:
+    Arg3 m_arg3;
+
+  public:
+    explicit GenericEvent4(const EventSender &sender) :
+        GenericEvent3<Arg0Type, Arg1Type, Arg2Type>(sender)
+    {}
+
+    GenericEvent4(Arg0 arg0,
+                  Arg1 arg1,
+                  Arg2 arg2,
+                  Arg3 arg3,
+                  const EventSender &sender) :
+        GenericEvent3<Arg0Type, Arg1Type, Arg2Type>(arg0, arg1, arg2, sender),
+        m_arg3(arg3)
+    {}
+
+    virtual ~GenericEvent4()
+    {}
+
+    Arg3 GetArg3() const
+    {
+        return m_arg3;
+    }
+};
+
+template<typename Arg0Type, typename Arg1Type, typename Arg2Type,
+         typename Arg3Type, typename Arg4Type>
+class GenericEvent5 :
+    public GenericEvent4<Arg0Type, Arg1Type, Arg2Type, Arg3Type>
+{
+  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<Arg0Type, Arg1Type, Arg2Type, Arg3Type>(sender)
+    {}
+
+    GenericEvent5(Arg0 arg0,
+                  Arg1 arg1,
+                  Arg2 arg2,
+                  Arg3 arg3,
+                  Arg4 arg4,
+                  const EventSender &sender) :
+        GenericEvent4<Arg0Type, Arg1Type, Arg2Type, Arg3Type>(arg0, arg1, arg2,
+                                                              arg3, sender),
+        m_arg4(arg4)
+    {}
+
+    virtual ~GenericEvent5()
+    {}
+
+    Arg4 GetArg4() const
+    {
+        return m_arg4;
+    }
+};
+
+template<typename Arg0Type, typename Arg1Type, typename Arg2Type,
+         typename Arg3Type, typename Arg4Type, typename Arg5Type>
+class GenericEvent6 :
+    public GenericEvent5<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type>
+{
+  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<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type>(sender)
+    {}
+
+    GenericEvent6(Arg0 arg0,
+                  Arg1 arg1,
+                  Arg2 arg2,
+                  Arg3 arg3,
+                  Arg4 arg4,
+                  Arg5 arg5,
+                  const EventSender &sender) :
+        GenericEvent5<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type>(arg0,
+                                                                        arg1,
+                                                                        arg2,
+                                                                        arg3,
+                                                                        arg4,
+                                                                        sender),
+        m_arg5(arg5)
+    {}
+
+    virtual ~GenericEvent6()
+    {}
+
+    Arg5 GetArg5() const
+    {
+        return m_arg5;
+    }
+};
+
+template<typename Arg0Type, typename Arg1Type, typename Arg2Type,
+         typename Arg3Type, typename Arg4Type, typename Arg5Type,
+         typename Arg6Type>
+class GenericEvent7 :
+    public GenericEvent6<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type,
+                         Arg5Type>
+{
+  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<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type,
+                      Arg5Type>(sender)
+    {}
+
+    GenericEvent7(Arg0 arg0,
+                  Arg1 arg1,
+                  Arg2 arg2,
+                  Arg3 arg3,
+                  Arg4 arg4,
+                  Arg5 arg5,
+                  Arg6 arg6,
+                  const EventSender &sender) :
+        GenericEvent6<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type,
+                      Arg5Type>(arg0, arg1, arg2, arg3, arg4, arg5, sender),
+        m_arg6(arg6)
+    {}
+
+    virtual ~GenericEvent7()
+    {}
+
+    Arg6 GetArg6() const
+    {
+        return m_arg6;
+    }
+};
+
+template<typename Arg0Type, typename Arg1Type, typename Arg2Type,
+         typename Arg3Type, typename Arg4Type, typename Arg5Type,
+         typename Arg6Type,
+         typename Arg7Type>
+class GenericEvent8 :
+    public GenericEvent7<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type,
+                         Arg5Type, Arg6Type>
+{
+  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<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type,
+                      Arg5Type, Arg6Type>(sender)
+    {}
+
+    GenericEvent8(Arg0 arg0,
+                  Arg1 arg1,
+                  Arg2 arg2,
+                  Arg3 arg3,
+                  Arg4 arg4,
+                  Arg5 arg5,
+                  Arg6 arg6,
+                  Arg7 arg7,
+                  const EventSender &sender) :
+        GenericEvent7<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type,
+                      Arg5Type, Arg6Type>(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<Arg0Type>                                 \
+    {                                                                         \
+      public:                                                                   \
+        explicit ClassName(const DPL::EventSender & sender = \
+                               DPL::EventSender(NULL)) :                                                                       \
+            DPL::GenericEvent1<Arg0Type>(sender)                            \
+        {                                                                     \
+        }                                                                     \
+                                                                              \
+        explicit ClassName(Arg0Type arg0,                                     \
+                           const DPL::EventSender & sender = \
+                               DPL::EventSender(NULL)) :                                                                 \
+            DPL::GenericEvent1<Arg0Type>(arg0, sender)                      \
+        {                                                                     \
+        }                                                                     \
+    };
+
+#define DECLARE_GENERIC_EVENT_2(ClassName, Arg0Type, Arg1Type)                \
+    class ClassName :                                                                     \
+        public DPL::GenericEvent2<Arg0Type, Arg1Type>                       \
+    {                                                                         \
+      public:                                                                   \
+        explicit ClassName(const DPL::EventSender & sender = \
+                               DPL::EventSender(NULL)) :                                                                       \
+            DPL::GenericEvent2<Arg0Type, Arg1Type>(sender)                  \
+        {                                                                     \
+        }                                                                     \
+                                                                              \
+        ClassName(Arg0Type arg0, Arg1Type arg1,                               \
+                  const DPL::EventSender & sender = DPL::EventSender(NULL)) :                                                                 \
+            DPL::GenericEvent2<Arg0Type, Arg1Type>(arg0, arg1, sender)      \
+        {                                                                     \
+        }                                                                     \
+    };
+
+#define DECLARE_GENERIC_EVENT_3(ClassName, Arg0Type, Arg1Type, Arg2Type)                      \
+    class ClassName :                                                                                     \
+        public DPL::GenericEvent3<Arg0Type, Arg1Type, Arg2Type>                             \
+    {                                                                                         \
+      public:                                                                                   \
+        explicit ClassName(const DPL::EventSender & sender = \
+                               DPL::EventSender(NULL)) :                                                                                 \
+            DPL::GenericEvent3<Arg0Type, Arg1Type, Arg2Type>(sender)                        \
+        {                                                                                     \
+        }                                                                                     \
+                                                                                              \
+        ClassName(Arg0Type arg0, Arg1Type arg1, Arg2Type arg2,                                \
+                  const DPL::EventSender & sender = DPL::EventSender(NULL)) :                                                                                 \
+            DPL::GenericEvent3<Arg0Type, Arg1Type, Arg2Type>(arg0, \
+                                                             arg1, \
+                                                             arg2, \
+                                                             sender)      \
+        {                                                                                     \
+        }                                                                                     \
+    };
+
+#define DECLARE_GENERIC_EVENT_4(ClassName, \
+                                Arg0Type, \
+                                Arg1Type, \
+                                Arg2Type, \
+                                Arg3Type)                            \
+    class ClassName :                                                                                                     \
+        public DPL::GenericEvent4<Arg0Type, Arg1Type, Arg2Type, Arg3Type>                                   \
+    {                                                                                                         \
+      public:                                                                                                   \
+        explicit ClassName(const DPL::EventSender & sender = \
+                               DPL::EventSender(NULL)) :                                                                                                 \
+            DPL::GenericEvent4<Arg0Type, Arg1Type, Arg2Type, Arg3Type>(sender)                              \
+        {                                                                                                     \
+        }                                                                                                     \
+                                                                                                              \
+        ClassName(Arg0Type arg0, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3,                                 \
+                  const DPL::EventSender & sender = DPL::EventSender(NULL)) :                                                                                                 \
+            DPL::GenericEvent4<Arg0Type, Arg1Type, Arg2Type, Arg3Type>(arg0, \
+                                                                       arg1, \
+                                                                       arg2, \
+                                                                       arg3, \
+                                                                       sender)      \
+        {                                                                                                     \
+        }                                                                                                     \
+    };
+
+#define DECLARE_GENERIC_EVENT_5(ClassName, \
+                                Arg0Type, \
+                                Arg1Type, \
+                                Arg2Type, \
+                                Arg3Type, \
+                                Arg4Type)                                  \
+    class ClassName :                                                                                                                     \
+        public DPL::GenericEvent5<Arg0Type, Arg1Type, Arg2Type, Arg3Type, \
+                                  Arg4Type>                                         \
+    {                                                                                                                         \
+      public:                                                                                                                   \
+        explicit ClassName(const DPL::EventSender & sender = \
+                               DPL::EventSender(NULL)) :                                                                                                                 \
+            DPL::GenericEvent5<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type>( \
+                sender)                                    \
+        {                                                                                                                     \
+        }                                                                                                                     \
+                                                                                                                              \
+        ClassName(Arg0Type arg0, \
+                  Arg1Type arg1, \
+                  Arg2Type arg2, \
+                  Arg3Type arg3, \
+                  Arg4Type arg4,                                  \
+                  const DPL::EventSender & sender = DPL::EventSender(NULL)) :                                                                                                                 \
+            DPL::GenericEvent5<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type>( \
+                arg0, \
+                arg1, \
+                arg2, \
+                arg3, \
+                arg4, \
+                sender)      \
+        {                                                                                                                     \
+        }                                                                                                                     \
+    };
+
+#define DECLARE_GENERIC_EVENT_6(ClassName, \
+                                Arg0Type, \
+                                Arg1Type, \
+                                Arg2Type, \
+                                Arg3Type, \
+                                Arg4Type, \
+                                Arg5Type)                                        \
+    class ClassName :                                                                                                                                     \
+        public DPL::GenericEvent6<Arg0Type, Arg1Type, Arg2Type, Arg3Type, \
+                                  Arg4Type, Arg5Type>                                               \
+    {                                                                                                                                         \
+      public:                                                                                                                                   \
+        explicit ClassName(const DPL::EventSender & sender = \
+                               DPL::EventSender(NULL)) :                                                                                                                                 \
+            DPL::GenericEvent6<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type, \
+                               Arg5Type>(sender)                                          \
+        {                                                                                                                                     \
+        }                                                                                                                                     \
+                                                                                                                                              \
+        ClassName(Arg0Type arg0, \
+                  Arg1Type arg1, \
+                  Arg2Type arg2, \
+                  Arg3Type arg3, \
+                  Arg4Type arg4, \
+                  Arg5Type arg5,                                   \
+                  const DPL::EventSender & sender = DPL::EventSender(NULL)) :                                                                                                                                 \
+            DPL::GenericEvent6<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type, \
+                               Arg5Type>(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<Arg0Type, Arg1Type, Arg2Type, Arg3Type, \
+                                  Arg4Type, Arg5Type, Arg6Type>                                                     \
+    {                                                                                                                                                         \
+      public:                                                                                                                                                   \
+        explicit ClassName(const DPL::EventSender & sender = \
+                               DPL::EventSender(NULL)) :                                                                                                                                                 \
+            DPL::GenericEvent7<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type, \
+                               Arg5Type, Arg6Type>(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<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type, \
+                               Arg5Type, Arg6Type>(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<Arg0Type, Arg1Type, Arg2Type, Arg3Type, \
+                                  Arg4Type, Arg5Type, Arg6Type, Arg7Type>                                                           \
+    {                                                                                                                                                                         \
+      public:                                                                                                                                                                   \
+        explicit ClassName(const DPL::EventSender & sender = \
+                               DPL::EventSender(NULL)) :                                                                                                                                                                 \
+            DPL::GenericEvent8<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type, \
+                               Arg5Type, Arg6Type, Arg7Type>(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<Arg0Type, Arg1Type, Arg2Type, Arg3Type, Arg4Type, \
+                               Arg5Type, Arg6Type, Arg7Type>(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 (file)
index 0000000..1b54026
--- /dev/null
@@ -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 <sstream>
+
+namespace DPL {
+template<typename TargetType, typename SourceType>
+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 (file)
index 0000000..cb088cf
--- /dev/null
@@ -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 <dpl/waitable_handle_watch_support.h>
+#include <dpl/exception.h>
+#include <dpl/singleton.h>
+#include <dpl/workaround.h>
+#include <dpl/framework_efl.h>
+#include <list>
+
+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<Ecore_Fd_Handler *> 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<Main> 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 (file)
index 0000000..9facbd3
--- /dev/null
@@ -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 <dpl/task.h>
+#include <list>
+
+namespace DPL {
+class MutableTaskList :
+    public Task
+{
+    private:
+        typedef std::list<Task *> 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 (file)
index 0000000..315a92c
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <pthread.h>
+
+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 (file)
index 0000000..45714ef
--- /dev/null
@@ -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 <dpl/exception.h>
+
+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 (file)
index 0000000..cf7b4b7
--- /dev/null
@@ -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 <dpl/exception.h>
+#include <dpl/named_base_pipe.h>
+#include <dpl/file_input.h>
+
+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 (file)
index 0000000..573d1d2
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <dpl/abstract_waitable_output.h>
+#include <dpl/named_base_pipe.h>
+
+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 (file)
index 0000000..98d57dd
--- /dev/null
@@ -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 (file)
index 0000000..ab3710f
--- /dev/null
@@ -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 <functional>
+#include <dpl/noncopyable.h>
+#include <dpl/atomic.h>
+#include <dpl/mutex.h>
+
+namespace DPL {
+class Once :
+    private Noncopyable
+{
+  public:
+    typedef std::function<void ()> 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 (file)
index 0000000..d1ec5f3
--- /dev/null
@@ -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 <dpl/exception.h>
+#include <dpl/availability.h>
+
+namespace DPL {
+template <typename Type>
+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<Type>& operator=(const Type& other)
+    {
+        m_null = false;
+        m_value = other;
+        return *this;
+    }
+
+    bool operator==(const Optional<Type>& aSecond) const
+    {
+        return LogicalOperator<true>(*this, aSecond,
+                                     std::equal_to<Type>(), std::equal_to<bool>());
+    }
+
+    bool operator==(const Type& aSecond) const
+    {
+        return Optional<Type>(aSecond) == *this;
+    }
+
+    bool operator!=(const Optional<Type>& aSecond) const
+    {
+        return !(*this == aSecond);
+    }
+
+    bool operator<(const Optional<Type>& aSecond) const
+    {
+        return LogicalOperator<false>(*this, aSecond,
+                                      std::less<Type>(), std::less<bool>());
+    }
+
+    bool operator>(const Optional<Type>& aSecond) const
+    {
+        return LogicalOperator<false>(*this, aSecond,
+                                      std::greater<Type>(), std::greater<bool>());
+    }
+
+    bool operator<=(const Optional<Type>& aSecond) const
+    {
+        return *this == aSecond || *this < aSecond;
+    }
+
+    bool operator>=(const Optional<Type>& aSecond) const
+    {
+        return *this == aSecond || *this > aSecond;
+    }
+
+    static Optional<Type> Null;
+
+  private:
+    bool m_null;
+    Type m_value;
+
+    template <bool taEquality, typename taComparator, typename taNullComparator>
+    static bool LogicalOperator(const Optional<Type>& aFirst,
+                                const Optional<Type>& 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<typename Type>
+Optional<Type> Optional<Type>::Null = Optional<Type>();
+} //namespace DPL
+
+template<typename Type>
+std::ostream& operator<<(std::ostream& aStream,
+                         const DPL::Optional<Type>& 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 (file)
index 0000000..8b56b4c
--- /dev/null
@@ -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 <string>
+#include <dpl/string.h>
+#include <dpl/optional.h>
+
+namespace DPL {
+typedef Optional<String> OptionalString;
+typedef Optional<int> OptionalInt;
+typedef Optional<unsigned int> OptionalUInt;
+typedef Optional<bool> OptionalBool;
+typedef Optional<float> OptionalFloat;
+typedef Optional<std::string> 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 (file)
index 0000000..d910f5c
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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 : <text>
+//               <text>
+// Author : <text>(<email>) - <date>
+// #define USE_<DEPENDENT_MODULE_NAME>_<FEATURE_NAME> <value>(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
+
+// Description : Support web-provider
+//               Livebox for webapp is valid in the platform depends on home screen.
+// Author : Jihoon Chung(jihoon.chung@samsung.com) - 05.23.2014
+#define USE_WEB_PROVIDER 1
+
+// Enable Features definition
+//   Turn on a specific feature of WRT
+//
+// Description : <text>
+//               <text>
+// Author : <text>(<email>) - <date>
+// #define ENABLE_<FEATURE_NAME> <value>(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
+
+// Description : Restrict Max Length of Config Element Attributes
+//               Wrt Installer restricts value of Element attributes' length to Maximum Length if defined.
+// Author : Sankeerth V S (sankeerth.vs@samsung.com) - 03.09.2014
+#define ENABLE_ELEMENT_ATTR_MAX_LENGTH 1
+
+// Description : Add Ellipsis at the end if element or attribute length exceeds the max allowed length
+//               as Wrt Installer restricts value of Element attributes' length to Maximum Length if defined.
+// Author : Sankeerth V S (sankeerth.vs@samsung.com) / Lalit Arora (lalit.arora@samsung.com) - 01.11.2014
+#define ENABLE_ADD_ELLIPSIS 0
+
+#endif // DPL_PLATFORM_H
diff --git a/modules/core/include/dpl/preprocessor.h b/modules/core/include/dpl/preprocessor.h
new file mode 100644 (file)
index 0000000..6fca34c
--- /dev/null
@@ -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 (file)
index 0000000..75d9f06
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <pthread.h>
+
+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 (file)
index 0000000..e4744cc
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <pthread.h>
+
+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 (file)
index 0000000..21a7b0c
--- /dev/null
@@ -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 <cstddef>
+#include <utility>
+#include <new>
+#include <type_traits>
+#include <dpl/preprocessor.h>
+
+namespace DPL {
+template<typename FunctionType>
+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<typename FunctionType>
+inline ScopeGuard<typename std::decay<FunctionType>::type>
+MakeScopeGuard(FunctionType&& function)
+{
+  return ScopeGuard<typename std::decay<FunctionType>::type>(
+          std::forward<FunctionType>(function));
+}
+
+namespace detail {
+enum class ScopeGuardOnExit {};
+
+template <typename FunctionType>
+inline ScopeGuard<typename std::decay<FunctionType>::type>
+operator+(detail::ScopeGuardOnExit, FunctionType&& function)
+{
+  return ScopeGuard<typename std::decay<FunctionType>::type>(
+          std::forward<FunctionType>(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 (file)
index 0000000..1be91bd
--- /dev/null
@@ -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<Type[]>
+ */
+#ifndef DPL_SCOPED_ARRAY_H
+#define DPL_SCOPED_ARRAY_H
+
+#include <cstddef>
+
+#include <dpl/assert.h>
+#include <dpl/scoped_resource.h>
+#include <dpl/availability.h>
+
+namespace DPL {
+template<typename Class>
+struct ScopedArrayPolicy
+{
+    typedef Class* Type;
+    static Type NullValue()
+    {
+        return NULL;
+    }
+    static void Destroy(Type ptr)
+    {
+        delete[] ptr;
+    }
+};
+
+template<typename Class>
+class ScopedArray : public ScopedResource<ScopedArrayPolicy<Class> >
+{
+    typedef ScopedArrayPolicy<Class> Policy;
+    typedef ScopedResource<Policy> 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<Type[]>");
+} // 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 (file)
index 0000000..45477af
--- /dev/null
@@ -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 <unistd.h>
+#include <cerrno>
+#include <string>
+#include <dpl/log/log.h>
+#include <dpl/scoped_resource.h>
+#include <dpl/errno_string.h>
+
+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<ScopedClosePolicy>
+{
+    typedef ScopedClosePolicy Policy;
+    typedef ScopedResource<Policy> 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 (file)
index 0000000..b10b4cc
--- /dev/null
@@ -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 <sys/stat.h>
+#include <sys/types.h>
+#include <string>
+#include <dpl/scoped_resource.h>
+
+namespace DPL {
+
+struct ScopedDirPolicy
+{
+    typedef std::string Type;
+    static Type NullValue();
+    static void Destroy(Type ptr);
+};
+
+class ScopedDir : public ScopedResource<ScopedDirPolicy>
+{
+    typedef ScopedDirPolicy Policy;
+    typedef ScopedResource<Policy> 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 (file)
index 0000000..b029803
--- /dev/null
@@ -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 <unistd.h>
+#include <cerrno>
+#include <cstdio>
+#include <string>
+#include <dpl/log/log.h>
+#include <dpl/scoped_resource.h>
+#include <dpl/errno_string.h>
+
+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<ScopedFClosePolicy>
+{
+    typedef ScopedFClosePolicy Policy;
+    typedef ScopedResource<Policy> 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 (file)
index 0000000..7bebe39
--- /dev/null
@@ -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 <malloc.h>
+#include <cstddef>
+
+#include <dpl/scoped_resource.h>
+
+namespace DPL {
+template<typename Class>
+struct ScopedFreePolicy
+{
+    typedef Class* Type;
+    static Type NullValue()
+    {
+        return NULL;
+    }
+    static void Destroy(Type ptr)
+    {
+        free(ptr);
+    }
+};
+
+template<typename Memory>
+class ScopedFree : public ScopedResource<ScopedFreePolicy<Memory> >
+{
+    typedef ScopedFreePolicy<Memory> Policy;
+    typedef ScopedResource<Policy> 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 (file)
index 0000000..6ccfd9e
--- /dev/null
@@ -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 <cstddef>
+#include <glib-object.h>
+#include <dpl/scoped_resource.h>
+#include <dpl/assert.h>
+#include <dpl/availability.h>
+
+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 <typename Class>
+class ScopedGPointer : public DPL::ScopedResource<ScopedGPointerPolicy>
+{
+    typedef ScopedGPointerPolicy Policy;
+    typedef DPL::ScopedResource<Policy> 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<Class *>(this->m_value);
+    }
+
+    Class & operator *() const throw()
+    {
+        Assert(this->m_value != Policy::NullValue() &&
+               "Dereference of scoped NULL pointer!");
+        return *static_cast<Class *>(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 (file)
index 0000000..0a2d01d
--- /dev/null
@@ -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 <cstddef>
+
+#include <dpl/scoped_resource.h>
+#include <dpl/assert.h>
+#include <dpl/availability.h>
+
+namespace DPL {
+template<typename Class>
+struct ScopedPtrPolicy
+{
+    typedef Class* Type;
+    static Type NullValue()
+    {
+        return NULL;
+    }
+    static void Destroy(Type ptr)
+    {
+        delete ptr;
+    }
+};
+
+template<typename Class, typename ClassPolicy = ScopedPtrPolicy<Class> >
+class ScopedPtr : public ScopedResource<ClassPolicy>
+{
+    typedef ClassPolicy Policy;
+    typedef ScopedResource<Policy> 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 (file)
index 0000000..63287da
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+
+namespace DPL {
+template<typename ClassPolicy>
+class ScopedResource :
+    private Noncopyable
+{
+  public:
+    typedef typename ClassPolicy::Type ValueType;
+    typedef ScopedResource<ClassPolicy> 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 (file)
index 0000000..0505621
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <semaphore.h>
+#include <string>
+
+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 (file)
index 0000000..d72c488
--- /dev/null
@@ -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 <string>
+#include <vector>
+#include <list>
+#include <map>
+
+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 <typename T>
+    static void Serialize(IStream& stream, const std::list<T>& list)
+    {
+        int length = list.size();
+        stream.Write(sizeof(length), &length);
+        for (typename std::list<T>::const_iterator list_iter = list.begin();
+             list_iter != list.end(); list_iter++)
+        {
+            Serialize(stream, *list_iter);
+        }
+    }
+    template <typename T>
+    static void Serialize(IStream& stream, const std::list<T>* const list)
+    {
+        Serialize(stream, *list);
+    }
+
+    // std::vector
+    template <typename T>
+    static void Serialize(IStream& stream, const std::vector<T>& vec)
+    {
+        int length = vec.size();
+        stream.Write(sizeof(length), &length);
+        for (typename std::vector<T>::const_iterator vec_iter = vec.begin();
+             vec_iter != vec.end(); vec_iter++)
+        {
+            Serialize(stream, *vec_iter);
+        }
+    }
+    template <typename T>
+    static void Serialize(IStream& stream, const std::vector<T>* const vec)
+    {
+        Serialize(stream, *vec);
+    }
+
+    // std::pair
+    template <typename A, typename B>
+    static void Serialize(IStream& stream, const std::pair<A, B>& p)
+    {
+        Serialize(stream, p.first);
+        Serialize(stream, p.second);
+    }
+    template <typename A, typename B>
+    static void Serialize(IStream& stream, const std::pair<A, B>* const p)
+    {
+        Serialize(stream, *p);
+    }
+
+    // std::map
+    template <typename K, typename T>
+    static void Serialize(IStream& stream, const std::map<K, T>& map)
+    {
+        int length = map.size();
+        stream.Write(sizeof(length), &length);
+        typename std::map<K, T>::const_iterator it;
+        for (it = map.begin(); it != map.end(); ++it) {
+            Serialize(stream, (*it).first);
+            Serialize(stream, (*it).second);
+        }
+    }
+    template <typename K, typename T>
+    static void Serialize(IStream& stream, const std::map<K, T>* 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 <typename T>
+    static void Deserialize(IStream& stream, T& object)
+    {
+        object = T(stream);
+    }
+    template <typename T>
+    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 <typename T>
+    static void Deserialize(IStream& stream, std::list<T>& 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 <typename T>
+    static void Deserialize(IStream& stream, std::list<T>*& list)
+    {
+        list = new std::list<T>;
+        Deserialize(stream, *list);
+    }
+
+    // std::vector
+    template <typename T>
+    static void Deserialize(IStream& stream, std::vector<T>& 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 <typename T>
+    static void Deserialize(IStream& stream, std::vector<T>*& vec)
+    {
+        vec = new std::vector<T>;
+        Deserialize(stream, *vec);
+    }
+
+    // std::pair
+    template <typename A, typename B>
+    static void Deserialize(IStream& stream, std::pair<A, B>& p)
+    {
+        Deserialize(stream, p.first);
+        Deserialize(stream, p.second);
+    }
+    template <typename A, typename B>
+    static void Deserialize(IStream& stream, std::pair<A, B>*& p)
+    {
+        p = new std::pair<A, B>;
+        Deserialize(stream, *p);
+    }
+
+    // std::map
+    template <typename K, typename T>
+    static void Deserialize(IStream& stream, std::map<K, T>& 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 <typename K, typename T>
+    static void Deserialize(IStream& stream, std::map<K, T>*& map)
+    {
+        map = new std::map<K, T>;
+        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 (file)
index 0000000..27f8b60
--- /dev/null
@@ -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 <stddef.h>
+
+#include <dpl/noncopyable.h>
+#include <dpl/atomic.h>
+#include <dpl/bool_operator.h>
+#include <dpl/assert.h>
+#include <dpl/availability.h>
+
+namespace DPL {
+struct StaticPointerCastTag {};
+struct ConstPointerCastTag {};
+struct DynamicPointerCastTag {};
+
+struct SharedCounter
+{
+    SharedCounter() :
+        ref(1)
+    {}
+
+    Atomic ref;
+};
+
+template<typename Class>
+class EnableSharedFromThis;
+
+template<typename Other>
+inline void _Internal_AcceptSharedPtr(SharedCounter *counter,
+                                      Other *other,
+                                      EnableSharedFromThis<Other> *otherBase)
+{
+    otherBase->_Internal_AcceptSharedPtr(counter, other);
+}
+
+struct AnyPointer
+{
+    template<typename Other>
+    AnyPointer(Other *)
+    {}
+};
+
+inline void _Internal_AcceptSharedPtr(SharedCounter *, AnyPointer, AnyPointer)
+{}
+
+template<typename Class>
+class SharedPtr
+{
+  public:
+    typedef Class ValueType;
+    typedef SharedPtr<Class> ThisType;
+
+  private:
+    SharedCounter *m_counter;
+    Class *m_ptr;
+
+    void AttachCounter(const SharedCounter *counter)
+    {
+        // Attention: R-Value const cast
+        m_counter = const_cast<SharedCounter *>(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<typename Other>
+    friend class SharedPtr;
+
+    template<typename Other>
+    SharedPtr(const SharedPtr<Other> &other, const StaticPointerCastTag &) :
+        m_counter(NULL),
+        m_ptr(NULL)
+    {
+        m_ptr = static_cast<Class *>(other.m_ptr);
+        AttachCounter(other.m_counter);
+    }
+
+    template<typename Other>
+    SharedPtr(const SharedPtr<Other> &other, const ConstPointerCastTag &) :
+        m_counter(NULL),
+        m_ptr(NULL)
+    {
+        m_ptr = const_cast<Class *>(other.m_ptr);
+        AttachCounter(other.m_counter);
+    }
+
+    template<typename Other>
+    SharedPtr(const SharedPtr<Other> &other, const DynamicPointerCastTag &) :
+        m_counter(NULL),
+        m_ptr(NULL)
+    {
+        Class *ptr = dynamic_cast<Class *>(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<typename Target, typename Source>
+SharedPtr<Target> StaticPointerCast(const SharedPtr<Source> &ptr)
+{
+    return SharedPtr<Target>(ptr, StaticPointerCastTag());
+}
+
+template<typename Target, typename Source>
+SharedPtr<Target> ConstPointerCast(const SharedPtr<Source> &ptr)
+{
+    return SharedPtr<Target>(ptr, ConstPointerCastTag());
+}
+
+template<typename Target, typename Source>
+SharedPtr<Target> DynamicPointerCast(const SharedPtr<Source> &ptr)
+{
+    return SharedPtr<Target>(ptr, DynamicPointerCastTag());
+}
+
+template<typename First, typename Second>
+inline bool operator ==(const SharedPtr<First> &first,
+                        const SharedPtr<Second> &second)
+{
+    return first.Get() == second.Get();
+}
+
+template<typename First, typename Second>
+inline bool operator !=(const SharedPtr<First> &first,
+                        const SharedPtr<Second> &second)
+{
+    return first.Get() != second.Get();
+}
+
+template<typename First, typename Second>
+inline bool operator <(const SharedPtr<First> &first,
+                       const SharedPtr<Second> &second)
+{
+    return first.Get() < second.Get();
+}
+template<typename First, typename Second>
+inline bool operator >(const SharedPtr<First> &first,
+                       const SharedPtr<Second> &second)
+{
+    return first.Get() > second.Get();
+}
+
+template<typename First, typename Second>
+inline bool operator <=(const SharedPtr<First> &first,
+                        const SharedPtr<Second> &second)
+{
+    return first.Get() <= second.Get();
+}
+
+template<typename First, typename Second>
+inline bool operator >=(const SharedPtr<First> &first,
+                        const SharedPtr<Second> &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 (file)
index 0000000..afcaf52
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <string>
+
+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 (file)
index 0000000..530f5c1
--- /dev/null
@@ -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 <dpl/optional.h>
+#include <dpl/thread.h>
+#include <dpl/assert.h>
+
+namespace DPL {
+template<typename Class>
+class Singleton :
+    private Class
+{
+    //
+    // Note:
+    //
+    // To remove posibility of instantiating directly Class,
+    // make Class' default constructor protected
+    //
+
+  private:
+    Singleton()
+    {}
+
+    typedef Optional<Thread *> 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 (file)
index 0000000..12dbf32
--- /dev/null
@@ -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<typename Class>
+Singleton<Class>& Singleton<Class>::InternalInstance()
+{
+    static Singleton<Class> instance;
+    return instance;
+}
+
+template<typename Class>
+Class &Singleton<Class>::Instance()
+{
+    Singleton<Class>& instance = Singleton<Class>::InternalInstance();
+    return instance;
+}
+} // namespace DPL
+
+#define IMPLEMENT_SINGLETON(Type)                                           \
+    template DPL::Singleton<Type>&DPL::Singleton<Type>::InternalInstance();    \
+    template Type & DPL::Singleton<Type>::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 (file)
index 0000000..c8923b7
--- /dev/null
@@ -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<Class>&Singleton<Class>::InternalInstance()                         \
+    {                                                                              \
+        static Singleton<Class> instance;                                          \
+        return instance;                                                           \
+    }                                                                              \
+                                                                               \
+    template<>                                                                     \
+    Class & Singleton<Class>::Instance()                                            \
+    {                                                                              \
+        Singleton<Class>& instance = Singleton<Class>::InternalInstance();         \
+        return instance;                                                           \
+    }                                                                              \
+                                                                               \
+    template Singleton<Class>&Singleton<Class>::InternalInstance();               \
+    template Class & Singleton<Class>::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 (file)
index 0000000..aba4e0f
--- /dev/null
@@ -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 <sstream>
+#include <dpl/string.h>
+
+namespace DPL {
+// @brief DPL IStringStream
+typedef std::basic_istringstream<CharTraits::char_type,
+                                 CharTraits> IStringStream;
+
+// @brief DPL OStringStream
+typedef std::basic_ostringstream<CharTraits::char_type,
+                                 CharTraits> 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 (file)
index 0000000..62fae46
--- /dev/null
@@ -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 <dpl/preprocessor.h>
+
+//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 (file)
index 0000000..e4dc923
--- /dev/null
@@ -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 <dpl/exception.h>
+#include <dpl/char_traits.h>
+#include <string>
+#include <ostream>
+#include <numeric>
+
+namespace DPL {
+// @brief DPL string
+typedef std::basic_string<wchar_t, CharTraits> 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<typename StringType, typename Delimiters, typename InserterIterator>
+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<typename T> class ConcatFunc : public std::binary_function<T, T, T>
+{
+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>
+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<value> func(delim);
+    ForwardIterator init = begin;
+    return std::accumulate(++begin, end, *init, func);
+}
+
+template<class StringType> void TrimLeft(StringType & obj, typename StringType::const_pointer separators)
+{
+    obj.erase(0, obj.find_first_not_of(separators));
+}
+
+template<class StringType> void TrimRight(StringType & obj, typename StringType::const_pointer separators)
+{
+    obj.erase(obj.find_last_not_of(separators)+1);
+}
+
+template<class StringType> 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 (file)
index 0000000..fa5f3a3
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/foreach.h>
+#include <dpl/assert.h>
+#include <algorithm>
+#include <list>
+
+namespace DPL {
+
+class Task :
+    private Noncopyable
+{
+  public:
+    virtual ~Task() {}
+
+    virtual bool NextStep() = 0;
+    virtual bool Abort() = 0;
+    virtual size_t GetStepCount() const = 0;
+};
+
+template<typename Impl>
+class TaskDecl :
+    public Task
+{
+  protected:
+    typedef void (Impl::*Step)();
+
+  private:
+    typedef std::list<Step> 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<size_t>(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 (file)
index 0000000..c41de3f
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES 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 <dpl/waitable_handle_watch_support.h>
+#include <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <dpl/mutex.h>
+#include <dpl/assert.h>
+#include <dpl/optional.h>
+#include <stdint.h>
+#include <cstdlib>
+#include <pthread.h>
+#include <algorithm>
+#include <utility>
+#include <vector>
+#include <list>
+#include <map>
+
+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<InternalEvent> InternalEventList;
+
+    // Internal timed event list
+    typedef std::vector<InternalTimedEvent> 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<typename Type>
+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<pthread_key_t> 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<ManagedValue *>(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<ManagedValue *>(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<ManagedValue *>(pthread_getspecific(m_key));
+
+        if (!specific) {
+            return;
+        }
+
+        // TODO Should be an assert? is it developers fault to Reset Guarded
+        // value?
+        specific->guardKey = Optional<pthread_key_t>::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<ManagedValue *>(pthread_getspecific(m_key));
+
+        Assert(instance && "Failed to get the value");
+
+        instance->guardKey = guard ? m_key : Optional<pthread_key_t>::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 (file)
index 0000000..88afaf2
--- /dev/null
@@ -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 <cstddef>
+
+namespace DPL {
+class TypeListGuard
+{
+  public:
+    template<size_t Index>
+    struct Element
+    {
+        struct ERROR_TypeListElementIndexIsOutOfBounds;
+        typedef ERROR_TypeListElementIndexIsOutOfBounds Type;
+    };
+
+    static const size_t Size = 0;
+};
+
+template<typename HeadType, typename TailType>
+class TypeList
+{
+  private:
+    class DummyClass
+    {};
+
+    template<typename List, size_t Enum>
+    struct TypeCounter : public TypeCounter<typename List::Tail, Enum + 1>
+    {};
+
+    template<size_t Enum>
+    struct TypeCounter<TypeListGuard, Enum>
+    {
+        static const size_t Size = Enum;
+    };
+
+  public:
+    typedef TailType Tail;
+    typedef HeadType Head;
+    typedef TypeList<HeadType, TailType> ThisType;
+
+    template<size_t Index, typename DummyType = DummyClass>
+    struct Element
+    {
+        typedef typename TailType::template Element<Index - 1>::Type Type;
+    };
+
+    template<typename DummyType>
+    struct Element<0, DummyType>
+    {
+        typedef HeadType Type;
+    };
+
+    template<typename Type, typename DummyType = DummyClass>
+    struct Contains
+    {
+        typedef typename TailType::template Contains<Type>::Yes Yes;
+    };
+
+    template<typename DummyType>
+    struct Contains<HeadType, DummyType>
+    {
+        typedef int Yes;
+    };
+
+    static const size_t Size = TypeCounter<ThisType, 0>::Size;
+};
+
+template<typename T1 = TypeListGuard, typename T2 = TypeListGuard,
+         typename T3 = TypeListGuard, typename T4 = TypeListGuard,
+         typename T5 = TypeListGuard, typename T6 = TypeListGuard,
+         typename T7 = TypeListGuard, typename T8 = TypeListGuard,
+         typename T9 = TypeListGuard, typename T10 = TypeListGuard,
+         typename T11 = TypeListGuard, typename T12 = TypeListGuard,
+         typename T13 = TypeListGuard, typename T14 = TypeListGuard,
+         typename T15 = TypeListGuard, typename T16 = TypeListGuard,
+         typename T17 = TypeListGuard, typename T18 = TypeListGuard,
+         typename T19 = TypeListGuard, typename T20 = TypeListGuard,
+         typename T21 = TypeListGuard, typename T22 = TypeListGuard,
+         typename T23 = TypeListGuard, typename T24 = TypeListGuard,
+         typename T25 = TypeListGuard, typename T26 = TypeListGuard,
+         typename T27 = TypeListGuard, typename T28 = TypeListGuard,
+         typename T29 = TypeListGuard, typename T30 = TypeListGuard,
+         typename T31 = TypeListGuard, typename T32 = TypeListGuard,
+         typename T33 = TypeListGuard, typename T34 = TypeListGuard,
+         typename T35 = TypeListGuard, typename T36 = TypeListGuard,
+         typename T37 = TypeListGuard, typename T38 = TypeListGuard,
+         typename T39 = TypeListGuard, typename T40 = TypeListGuard,
+         typename T41 = TypeListGuard, typename T42 = TypeListGuard,
+         typename T43 = TypeListGuard, typename T44 = TypeListGuard,
+         typename T45 = TypeListGuard, typename T46 = TypeListGuard,
+         typename T47 = TypeListGuard, typename T48 = TypeListGuard,
+         typename T49 = TypeListGuard, typename T50 = TypeListGuard,
+         typename T51 = TypeListGuard, typename T52 = TypeListGuard,
+         typename T53 = TypeListGuard, typename T54 = TypeListGuard,
+         typename T55 = TypeListGuard, typename T56 = TypeListGuard,
+         typename T57 = TypeListGuard, typename T58 = TypeListGuard,
+         typename T59 = TypeListGuard, typename T60 = TypeListGuard,
+         typename T61 = TypeListGuard, typename T62 = TypeListGuard,
+         typename T63 = TypeListGuard, typename T64 = TypeListGuard>
+struct TypeListDecl
+{
+    typedef TypeList<T1,
+                     typename TypeListDecl<
+                         T2, T3, T4, T5, T6, T7, T8,
+                         T9, T10, T11, T12, T13, T14, T15,
+                         T16, T17, T18, T19, T20, T21, T22,
+                         T23, T24, T25, T26, T27, T28, T29,
+                         T30, T31, T32, T33, T34, T35, T36,
+                         T37, T38, T39, T40, T41, T42, T43,
+                         T44, T45, T46, T47, T48, T49, T50,
+                         T51, T52, T53, T54, T55, T56, T57,
+                         T58, T59, T60, T61, T62, T63, T64>::Type> Type;
+};
+
+template<>
+struct TypeListDecl<TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+                    TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard>
+{
+    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 (file)
index 0000000..3f499a4
--- /dev/null
@@ -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 <cstring>
+
+namespace DPL {
+template<typename TargetType, typename SourceType>
+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 (file)
index 0000000..364bc5c
--- /dev/null
@@ -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 <dpl/waitable_handle.h>
+#include <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <vector>
+
+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 (file)
index 0000000..9864f78
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <vector>
+
+namespace DPL {
+/**
+ * Waitable unix wait handle definition
+ */
+typedef int WaitableHandle;
+
+/**
+ * Waitable handle list
+ */
+typedef std::vector<WaitableHandle> 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<std::pair<WaitableHandle,
+                              WaitMode::Type> > WaitableHandleListEx;
+
+/**
+ * Waitable handle index list
+ */
+typedef std::vector<size_t> 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 (file)
index 0000000..ac0987f
--- /dev/null
@@ -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 <dpl/waitable_event.h>
+#include <dpl/waitable_handle.h>
+#include <dpl/exception.h>
+#include <dpl/recursive_mutex.h>
+#include <list>
+#include <map>
+
+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<WaitableHandleWatcher> WaitableHandleListenerList;
+
+    struct WaitableHandleWatchers
+    {
+        WaitableHandleListenerList listeners;
+        size_t readListenersCount;
+        size_t writeListenersCount;
+
+        WaitableHandleWatchers() :
+            readListenersCount(0),
+            writeListenersCount(0)
+        {}
+    };
+
+    typedef std::map<WaitableHandle,
+                     WaitableHandleWatchers> 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 (file)
index 0000000..19c26ef
--- /dev/null
@@ -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 (file)
index 0000000..b364fe4
--- /dev/null
@@ -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 <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <dpl/abstract_input.h>
+#include <utility>
+#include <vector>
+#include <string>
+
+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<size_t, size_t> 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<FileInfo> 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 (file)
index 0000000..9043c93
--- /dev/null
@@ -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 (file)
index 0000000..a802a7f
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+
+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 (file)
index 0000000..e432b31
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/abstract_waitable_input_output_adapter.h>
+
+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 (file)
index 0000000..82c2347
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/abstract_waitable_output_adapter.h>
+
+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 (file)
index 0000000..34c8861
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/address.h>
+#include <sstream>
+#include <dpl/assert.h>
+
+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 (file)
index 0000000..9335ded
--- /dev/null
@@ -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        application.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of MVC application support
+ */
+#include <stddef.h>
+#include <dpl/application.h>
+#include <dpl/log/log.h>
+
+namespace // anonymous
+{
+static DPL::Application *g_application = NULL;
+} // namespace anonymous
+
+namespace DPL {
+bool Application::app_create(void *data)
+{
+    Application *This = static_cast<Application *>(data);
+    This->OnCreate();
+    return true;
+}
+
+void Application::app_terminate(void *data)
+{
+    Application *This = static_cast<Application *>(data);
+    This->OnTerminate();
+}
+
+void Application::app_pause(void *data)
+{
+    Application *This = static_cast<Application *>(data);
+    This->OnPause();
+}
+
+void Application::app_resume(void *data)
+{
+    Application *This = static_cast<Application *>(data);
+    This->OnResume();
+}
+
+void Application::app_control(app_control_h app_control, void *data)
+{
+    Application *This = static_cast<Application *>(data);
+
+    // convert app_control to bundle
+    bundle *b;
+    app_control_to_bundle(app_control, &b);
+
+    This->OnReset(b);
+}
+
+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...");
+
+    ui_app_lifecycle_callback_s callback;
+    callback.create = app_create;
+    callback.terminate = app_terminate;
+    callback.pause = app_pause;
+    callback.resume = app_resume;
+    callback.app_control = app_control;
+
+    int result = ui_app_main(m_argc, m_argv, &callback, this);
+
+    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 (file)
index 0000000..7ba5180
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/apply.h>
+
+//
+// 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 (file)
index 0000000..5a18977
--- /dev/null
@@ -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 <stdio.h>
+#include <stddef.h>
+#include <dpl/assert.h>
+#include <dpl/colors.h>
+#include <dpl/log/log.h>
+#include <cstdlib>
+
+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 (file)
index 0000000..2f50074
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/atomic.h>
+
+namespace DPL {
+Atomic::Atomic(ValueType value) :
+    m_value(value)
+{}
+
+Atomic::ValueType Atomic::ExchangeAndAdd(ValueType value)
+{
+    return g_atomic_int_add(const_cast<gint* >(&m_value), value);
+}
+
+bool Atomic::CompareAndExchange(ValueType oldValue, ValueType newValue)
+{
+    return g_atomic_int_compare_and_exchange(const_cast<gint* >(&m_value),
+                                             oldValue,
+                                             newValue);
+}
+
+bool Atomic::operator--()
+{
+    return g_atomic_int_dec_and_test(const_cast<gint* >(&m_value)) != TRUE;
+}
+
+void Atomic::operator++()
+{
+    g_atomic_int_inc(const_cast<gint* >(&m_value));
+}
+
+Atomic::operator ValueType() const
+{
+    return g_atomic_int_get(const_cast<gint* >(&m_value));
+}
+} // namespace DPL
diff --git a/modules/core/src/binary_queue.cpp b/modules/core/src/binary_queue.cpp
new file mode 100644 (file)
index 0000000..2234c8f
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/binary_queue.h>
+#include <dpl/assert.h>
+#include <dpl/scoped_free.h>
+#include <algorithm>
+#include <malloc.h>
+#include <cstring>
+#include <new>
+
+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<const char *>(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<char *>(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<void *>(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<void> 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 (file)
index 0000000..32b9197
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/char_traits.h>
+
+//
+// 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 (file)
index 0000000..0b2fcd4
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/colors.h>
+
+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 = "<font color=\"green\"><b>";
+const char* BOLD_GREEN_END = "</b></font>";
+const char* PURPLE_BEGIN = "<font color=\"purple\"><b>";
+const char* PURPLE_END = "</b></font>";
+const char* RED_BEGIN = "<font color=\"red\"><b>";
+const char* RED_END = "</b></font>";
+const char* GREEN_BEGIN = "<font color=\"green\">";
+const char* GREEN_END = "</font>";
+const char* CYAN_BEGIN = "<font color=\"cyan\">";
+const char* CYAN_END = "</font>";
+const char* BOLD_RED_BEGIN = "<font color=\"red\"><b>";
+const char* BOLD_RED_END = "</b></font>";
+const char* BOLD_YELLOW_BEGIN = "<font color=\"yellow\"><b>";
+const char* BOLD_YELLOW_END = "</b></font>";
+const char* BOLD_GOLD_BEGIN = "<font color=\"gold\"><b>";
+const char* BOLD_GOLD_END = "</b></font>";
+const char* BOLD_WHITE_BEGIN = "<font color=\"white\"><b>";
+const char* BOLD_WHITE_END = "</b></font>";
+} //namespace Html
+} //namespace Colors
+} //namespace DPL
diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp
new file mode 100644 (file)
index 0000000..c05d06c
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/copy.h>
+#include <dpl/waitable_handle.h>
+#include <dpl/binary_queue.h>
+
+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 (file)
index 0000000..86cb59b
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/errno_string.h>
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/assert.h>
+#include <dpl/scoped_free.h>
+#include <string>
+#include <cstddef>
+#include <cstring>
+#include <malloc.h>
+#include <cerrno>
+#include <stdexcept>
+
+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<char *>(::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<char> 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<char> 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 (file)
index 0000000..d3673e6
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/exception.h>
+#include <dpl/log/log.h>
+#include <cstdio>
+
+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 (file)
index 0000000..36fb4b5
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/file_input.h>
+#include <dpl/binary_queue.h>
+#include <dpl/log/log.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+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<WaitableHandle>(m_fd);
+}
+} // namespace DPL
diff --git a/modules/core/src/file_output.cpp b/modules/core/src/file_output.cpp
new file mode 100644 (file)
index 0000000..8342698
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/file_output.h>
+#include <dpl/binary_queue.h>
+#include <dpl/scoped_free.h>
+#include <dpl/log/log.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+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<void> 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<size_t>(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<WaitableHandle>(m_fd);
+}
+} // namespace DPL
diff --git a/modules/core/src/generic_event.cpp b/modules/core/src/generic_event.cpp
new file mode 100644 (file)
index 0000000..f09ff2b
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/generic_event.h>
+
+//
+// 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 (file)
index 0000000..a89abc9
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/lexical_cast.h>
+
+//
+// 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 (file)
index 0000000..1d0326b
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/main.h>
+#include <dpl/log/log.h>
+#include <sys/select.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dpl/assert.h>
+#include <dpl/singleton_impl.h>
+
+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<Main *>(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<Main *>(data);
+
+    Assert(This != NULL);
+
+    // Late EFL event handling
+    if (g_lateMain == NULL) {
+        LogPedantic("WARNING: Late EFL read watcher dispatch!");
+    } else {
+        This->DispatchReadWatcher(static_cast<WaitableHandle>(
+                                      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<Main *>(data);
+
+    Assert(This != NULL);
+
+    // Late EFL event handling
+    if (g_lateMain == NULL) {
+        LogPedantic("WARNING: Late EFL write watcher dispatch!");
+    } else {
+        This->DispatchWriteWatcher(static_cast<WaitableHandle>(
+                                       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<WaitableHandle>(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<WaitableHandle>(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<WaitableHandle>(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<WaitableHandle>(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 (file)
index 0000000..f8886fa
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/mutable_task_list.h>
+#include <dpl/assert.h>
+
+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 (file)
index 0000000..eed1f2e
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/mutex.h>
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+#include <errno.h>
+
+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 (file)
index 0000000..9f91d30
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/named_base_pipe.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+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 (file)
index 0000000..2a9a1fa
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/named_output_pipe.h>
+#include <dpl/binary_queue.h>
+#include <dpl/scoped_free.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+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<void> 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<size_t>(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 (file)
index 0000000..9453655
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/noncopyable.h>
+
+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 (file)
index 0000000..f2d4a1a
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/once.h>
+
+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 (file)
index 0000000..ef34758
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/read_write_mutex.h>
+#include <dpl/assert.h>
+
+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 (file)
index 0000000..234d25f
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/recursive_mutex.h>
+#include <dpl/assert.h>
+
+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 (file)
index 0000000..96550e6
--- /dev/null
@@ -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 <dpl/scoped_dir.h>
+#include <dpl/errno_string.h>
+#include <dpl/log/log.h>
+
+#include <fts.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace {
+
+bool removeRecusive(const char * path)
+{
+    FTS *fts;
+    FTSENT *ftsent;
+    bool rv = true;
+    char * const paths[] = { const_cast<char * const>(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 (file)
index 0000000..387c009
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/semaphore.h>
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+#include <errno.h>
+#include <malloc.h>
+#include <cstring>
+#include <fcntl.h>
+#include <unistd.h>
+
+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<unsigned>(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<unsigned>(maxLockCount));
+            } else {
+                semaphore = sem_open(fileName.c_str(),
+                                     O_CREAT,
+                                     permissions,
+                                     static_cast<unsigned>(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 (file)
index 0000000..f8f05ff
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/serialization.h>
+
+//
+// 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 (file)
index 0000000..274b5f8
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/single_instance.h>
+#include <dpl/log/log.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dpl/assert.h>
+
+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 (file)
index 0000000..a76e8ac
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/singleton.h>
+
+//
+// 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 (file)
index 0000000..e81ae22
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/string.h>
+#include <dpl/char_traits.h>
+#include <dpl/errno_string.h>
+#include <dpl/exception.h>
+#include <dpl/scoped_array.h>
+#include <dpl/log/log.h>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <cstring>
+#include <errno.h>
+#include <iconv.h>
+#include <unicode/ustring.h>
+
+// 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<int>(aCharacter)
+                                      << " from string [" <<
+            m_TestedString
+                                      << "] passed as ASCII");
+    }
+}
+
+const iconv_t gc_IconvOperError = reinterpret_cast<iconv_t>(-1);
+const size_t gc_IconvConvertError = static_cast<size_t>(-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<wchar_t> output(inbytes + 2, 0);
+
+    size_t outbytesleft = outbytes;
+    char* inbuf = const_cast<char*>(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<char*>(&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<char*>(const_cast<wchar_t*>(aIn.c_str()));
+    std::vector<char> 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<String>(output));
+
+    return output;
+}
+
+String FromUTF32String(const std::wstring& aString)
+{
+    return String(&aString[0]);
+}
+
+static UChar *ConvertToICU(const String &inputString)
+{
+    ScopedArray<UChar> 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<UChar> leftICU(ConvertToICU(left));
+    ScopedArray<UChar> rightICU(ConvertToICU(right));
+
+    if (caseInsensitive) {
+        return static_cast<int>(u_strcasecmp(leftICU.Get(), rightICU.Get(), 0));
+    } else {
+        return static_cast<int>(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 (file)
index 0000000..6d4ff0d
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/task.h>
+
+//
+// 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 (file)
index 0000000..0e75810
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/thread.h>
+#include <dpl/log/log.h>
+#include <sys/time.h>
+#include <algorithm>
+#include <dpl/assert.h>
+#include <errno.h>
+#include <time.h>
+#include <string.h>
+
+namespace // anonymous
+{
+static const size_t NANOSECONDS_PER_SECOND =
+    static_cast<uint64_t>(1000 * 1000 * 1000);
+
+static const size_t NANOSECONDS_PER_MILISECOND =
+    static_cast<uint64_t>(1000 * 1000);
+
+static const size_t NANOSECONDS_PER_MICROSECOND =
+    static_cast<uint64_t>(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<Thread *>(threadSpecific);
+}
+
+void *Thread::StaticThreadEntry(void *param)
+{
+    LogPedantic("Entered static thread entry");
+
+    // Retrieve context
+    Thread *This = static_cast<Thread *>(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<unsigned long>(tv.tv_sec) * 1000 +
+           static_cast<unsigned long>(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<WaitableHandle,
+                              WaitMode::Type> 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<unsigned long>(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<time_t>(
+            nanoseconds / NANOSECONDS_PER_SECOND),
+
+        static_cast<long>(
+            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 (file)
index 0000000..fa94806
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/type_list.h>
+
+//
+// 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 (file)
index 0000000..ffcb499
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/union_cast.h>
+
+//
+// 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 (file)
index 0000000..4808896
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/waitable_event.h>
+#include <sys/select.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <errno.h>
+
+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 (file)
index 0000000..5ea600d
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/waitable_event.h>
+#include <dpl/workaround.h>
+#include <dpl/log/log.h>
+#include <sys/select.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dpl/assert.h>
+
+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 (file)
index 0000000..53f8b65
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/waitable_handle_watch_support.h>
+#include <dpl/thread.h>
+#include <dpl/main.h>
+#include <dpl/log/log.h>
+#include <algorithm>
+#include <dpl/assert.h>
+
+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 (file)
index 0000000..fadc60f
--- /dev/null
@@ -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 <stddef.h>
+#include <iomanip>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dpl/zip_input.h>
+#include <dpl/scoped_close.h>
+#include <dpl/binary_queue.h>
+#include <dpl/scoped_free.h>
+#include <memory>
+#include <dpl/scoped_array.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <new>
+#include <minizip/unzip.h>
+
+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<off64_t>(-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_t>(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<unsigned char *>(address);
+
+        LogPedantic("Created file mapping: " << fileName <<
+                    " of size: " << m_size <<
+                    " at address: " << std::hex <<
+                    static_cast<void *>(m_address));
+    }
+
+    ~Device()
+    {
+        // Close mapping
+        if (munmap(m_address, static_cast<size_t>(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<Device *>(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<Device *>(opaque);
+        File *deviceFile = static_cast<File *>(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<off64_t>(size) > bytesLeft) {
+            bytesToRead = bytesLeft;
+        } else {
+            bytesToRead = static_cast<off64_t>(size);
+        }
+
+        // Do copy
+        memcpy(buf,
+               device->m_address + deviceFile->offset,
+               static_cast<size_t>(bytesToRead));
+
+        // Increment file offset
+        deviceFile->offset += bytesToRead;
+
+        // Return bytes that were actually read
+        return static_cast<uLong>(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<File *>(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<File *>(stream);
+
+        return static_cast<ZPOS64_T>(deviceFile->offset);
+    }
+
+    static long ZCALLBACK seek64_file(voidpf opaque,
+                                      voidpf stream,
+                                      ZPOS64_T offset,
+                                      int origin)
+    {
+        Device *device = static_cast<Device *>(opaque);
+        File *deviceFile = static_cast<File *>(stream);
+
+        switch (origin) {
+        case ZLIB_FILEFUNC_SEEK_SET:
+            deviceFile->offset = static_cast<off64_t>(offset);
+
+            break;
+
+        case ZLIB_FILEFUNC_SEEK_CUR:
+            deviceFile->offset += static_cast<off64_t>(offset);
+
+            break;
+
+        case ZLIB_FILEFUNC_SEEK_END:
+            deviceFile->offset =
+                device->m_size -
+                static_cast<off64_t>(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> 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<unzFile>(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<unzFile>(masterFile),
+                         &globalInfo) != UNZ_OK)
+    {
+        LogPedantic("Failed to read zip global info");
+
+        ThrowMsg(Exception::ReadGlobalInfoFailed,
+                 "Failed to read global info");
+    }
+
+    m_numberOfFiles = static_cast<size_t>(globalInfo.number_entry);
+    m_globalCommentSize = static_cast<size_t>(globalInfo.size_comment);
+
+    LogPedantic("Number of files: " << m_numberOfFiles);
+    LogPedantic("Global comment size: " << m_globalCommentSize);
+}
+
+void ZipInput::ReadGlobalComment(void *masterFile)
+{
+    ScopedArray<char> comment(new char[m_globalCommentSize + 1]);
+
+    if (unzGetGlobalComment(static_cast<unzFile>(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<unzFile>(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<unzFile>(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<unzFile>(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<char> fileName(new char[fileInfo.size_filename + 1]);
+        ScopedArray<char> fileComment(new char[fileInfo.size_file_comment + 1]);
+
+        if (unzGetCurrentFileInfo64(static_cast<unzFile>(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<size_t>(filePos.pos_in_zip_directory),
+                    static_cast<size_t>(filePos.num_of_file)
+                    ),
+                std::string(fileName.Get()),
+                std::string(fileComment.Get()),
+                static_cast<off64_t>(fileInfo.compressed_size),
+                static_cast<off64_t>(fileInfo.uncompressed_size)
+                )
+            );
+        m_totalUncompressedSize += static_cast<size_t>(fileInfo.uncompressed_size);
+
+        // If this is not the last file, go to next one
+        if (i != m_numberOfFiles - 1) {
+            if (unzGoToNextFile(
+                    static_cast<unzFile>(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<ZPOS64_T>(handle.first),
+        static_cast<ZPOS64_T>(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<unzFile>(m_file)) != UNZ_OK) {
+        LogPedantic("Failed to close current zip input file");
+    }
+
+    // Close zip file
+    if (unzClose(static_cast<unzFile>(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<void> rawBuffer(malloc(sizeToRead));
+
+    if (!rawBuffer) {
+        throw std::bad_alloc();
+    }
+
+    // Do unpack
+    int bytes = unzReadCurrentFile(static_cast<unzFile>(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<size_t>(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 (file)
index 0000000..4a88649
--- /dev/null
@@ -0,0 +1,84 @@
+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
+    dlog
+    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 (file)
index 0000000..5f26fd7
--- /dev/null
@@ -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 <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
+
+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 (file)
index 0000000..6d57771
--- /dev/null
@@ -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 <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
+#include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
+#include <orm_generator_custom_handler.h>
+#include <wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h>
+
+using namespace DPL::DB::ORM;
+using namespace DPL::DB::ORM::custom_handler;
+
+namespace CustomHandlerDB {
+namespace {
+template <typename T>
+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<ContentHandlers::target>(handler.target),
+                              Or(Equals<ContentHandlers::user_allowed>(Agreed),
+                                 Equals<ContentHandlers::user_allowed>(
+                                     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<ContentHandlers::target>(
+                                             handler.target),
+                                         Or(Equals<ContentHandlers::
+                                                       user_allowed>(Agreed),
+                                            Equals<ContentHandlers::
+                                                       user_allowed>(
+                                                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<ContentHandlers::target>(handler.
+                                                                      target),
+                                  Or(Equals<ContentHandlers::user_allowed>(
+                                         Agreed),
+                                     Equals<ContentHandlers::user_allowed>(
+                                         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<ContentHandlers::app_id>(m_pkgName),
+                                 And(Equals<ContentHandlers::target>(handler.
+                                                                         target),
+                                     And(Equals<ContentHandlers::url>(handler.
+                                                                          url),
+                                         Equals<ContentHandlers::base_url>(
+                                             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<ProtocolHandlers::target>(handler.target),
+                              Or(Equals<ProtocolHandlers::user_allowed>(Agreed),
+                                 Equals<ProtocolHandlers::user_allowed>(
+                                     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<ProtocolHandlers::target>(
+                                              handler.target),
+                                          Or(Equals<ProtocolHandlers::
+                                                        user_allowed>(Agreed),
+                                             Equals<ProtocolHandlers::
+                                                        user_allowed>(
+                                                 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<ProtocolHandlers::target>(handler.
+                                                                       target),
+                                  Or(Equals<ProtocolHandlers::user_allowed>(
+                                         Agreed),
+                                     Equals<ProtocolHandlers::user_allowed>(
+                                         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<ProtocolHandlers::app_id>(m_pkgName),
+                                 And(Equals<ProtocolHandlers::target>(handler.
+                                                                          target),
+                                     And(Equals<ProtocolHandlers::url>(handler.
+                                                                           url),
+                                         Equals<ProtocolHandlers::base_url>(
+                                             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<ContentHandlers::app_id>(m_pkgName),
+                              And(Equals<ContentHandlers::target>(target),
+                                  Equals<ContentHandlers::url>(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<ProtocolHandlers::app_id>(m_pkgName),
+                              And(Equals<ProtocolHandlers::target>(target),
+                                  Equals<ProtocolHandlers::url>(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<ContentHandlers::app_id>(m_pkgName),
+                              And(Equals<ContentHandlers::target>(target),
+                                  And(Equals<ContentHandlers::url>(url),
+                                      Equals<ContentHandlers::base_url>(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<ProtocolHandlers::app_id>(m_pkgName),
+                              And(Equals<ProtocolHandlers::target>(target),
+                                  And(Equals<ProtocolHandlers::url>(url),
+                                      Equals<ProtocolHandlers::base_url>(
+                                          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<ProtocolHandlers::app_id>(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<ContentHandlers::app_id>(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 (file)
index 0000000..fd88c12
--- /dev/null
@@ -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 <wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h>
+#include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
+
+#include <orm_generator_custom_handler.h>
+
+using namespace DPL::DB::ORM;
+using namespace DPL::DB::ORM::custom_handler;
+
+namespace CustomHandlerDB {
+namespace {
+template <typename T>
+CustomHandlerPtr getSingleHandler(std::list<T> 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<HandlerState>(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<ProtocolHandlers::app_id>(m_pkgName),
+                          And(Equals<ProtocolHandlers::target>(protocol),
+                              Equals<ProtocolHandlers::url>(url))));
+
+        std::list<ProtocolHandlers::Row> 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<ContentHandlers::app_id>(m_pkgName),
+                          And(Equals<ContentHandlers::target>(content),
+                              Equals<ContentHandlers::url>(url))));
+
+        std::list<ContentHandlers::Row> 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<ProtocolHandlers::app_id>(m_pkgName),
+                          Equals<ProtocolHandlers::target>(protocol)));
+
+        std::list<ProtocolHandlers::Row> 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<HandlerState>(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<ProtocolHandlers::app_id>(m_pkgName),
+                          And(Equals<ProtocolHandlers::target>(protocol),
+                              And(Equals<ProtocolHandlers::url>(url),
+                                  Equals<ProtocolHandlers::base_url>(baseURL)
+                                  )
+                              )
+                          )
+                      );
+
+        std::list<ProtocolHandlers::Row> 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<ContentHandlers::app_id>(m_pkgName),
+                          Equals<ContentHandlers::target>(content)));
+
+        std::list<ContentHandlers::Row> 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<HandlerState>(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<ContentHandlers::app_id>(m_pkgName),
+                          And(Equals<ContentHandlers::target>(content),
+                              And(Equals<ContentHandlers::url>(url),
+                                  Equals<ContentHandlers::base_url>(baseURL)))));
+
+        std::list<ContentHandlers::Row> 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 (file)
index 0000000..4eabd55
--- /dev/null
@@ -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 <dpl/thread.h>
+#include <dpl/mutex.h>
+#include <dpl/db/thread_database_support.h>
+
+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<InternalType> *tlsCommand##Ptr = NULL;   \
+    {                                                                          \
+        DPL::Mutex::ScopedLock lock(                                           \
+            &CustomHandlerDB::Interface::g_dbQueriesMutex);                \
+        if (!tlsCommand##Ptr) {                                              \
+            static DPL::ThreadLocalVariable<InternalType> tmp;                 \
+            tlsCommand##Ptr = &tmp;                                          \
+        }                                                                      \
+    }                                                                          \
+    DPL::ThreadLocalVariable<InternalType> &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 (file)
index 0000000..e5a59f0
--- /dev/null
@@ -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 <list>
+#include <memory>
+#include <dpl/string.h>
+
+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<CustomHandler> CustomHandlerPtr;
+typedef std::list <CustomHandlerPtr> 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 (file)
index 0000000..8ad4979
--- /dev/null
@@ -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 <dpl/string.h>
+#include <dpl/exception.h>
+#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 (file)
index 0000000..9a478cb
--- /dev/null
@@ -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 <wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h>
+
+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 (file)
index 0000000..848c84a
--- /dev/null
@@ -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 (file)
index 0000000..1bc2bcd
--- /dev/null
@@ -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 (file)
index 0000000..9b007de
--- /dev/null
@@ -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 <dpl/db/orm_macros.h>
+
+#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 (executable)
index 0000000..22c2530
--- /dev/null
@@ -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 (file)
index 0000000..35c43a2
--- /dev/null
@@ -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 <dpl/db/orm_generator.h>
+#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 (file)
index 0000000..7e20d8d
--- /dev/null
@@ -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 (file)
index 0000000..96ccbb9
--- /dev/null
@@ -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 (file)
index 0000000..2f63a0f
--- /dev/null
@@ -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 <dpl/db/sql_connection.h>
+
+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 (file)
index 0000000..652e8e1
--- /dev/null
@@ -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 <cstdlib>
+#include <cstdio>
+#include <string>
+#include <typeinfo>
+#include <utility>
+#include <set>
+#include <memory>
+
+#include <dpl/db/sql_connection.h>
+#include <dpl/db/orm_interface.h>
+#include <dpl/string.h>
+#include <dpl/optional.h>
+#include <dpl/type_list.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+
+#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<DPL::String> OptionalString;
+typedef DPL::Optional<int> 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<Expression> ExpressionPtr;
+
+namespace OrderingUtils {
+
+template<typename CompoundType> inline std::string OrderByInternal()
+{
+    std::string order = OrderByInternal<typename CompoundType::Tail>();
+    if(!order.empty()) return CompoundType::Head::GetString() + ", " + order;
+    else return CompoundType::Head::GetString();
+}
+
+template<> inline std::string OrderByInternal<TypeListGuard>()
+{
+    return std::string();
+}
+
+}
+
+template<typename ColumnType>
+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<const char* Operator, typename LeftExpression, typename RightExpression>
+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<typename TableDefinition>
+    struct ValidForTable {
+        typedef std::pair<typename LeftExpression ::template ValidForTable<TableDefinition>::Yes ,
+                          typename RightExpression::template ValidForTable<TableDefinition>::Yes >
+                Yes;
+    };
+};
+
+template<typename LeftExpression, typename RightExpression>
+BinaryExpression<RelationTypes::And, LeftExpression, RightExpression>
+    And(const LeftExpression& leftExpression, const RightExpression& rightExpression)
+{
+    return BinaryExpression<RelationTypes::And, LeftExpression, RightExpression>
+            (leftExpression, rightExpression);
+}
+
+template<typename LeftExpression, typename RightExpression>
+BinaryExpression<RelationTypes::Or, LeftExpression, RightExpression>
+    Or(const LeftExpression& leftExpression, const RightExpression& rightExpression)
+{
+    return BinaryExpression<RelationTypes::Or, LeftExpression, RightExpression>
+            (leftExpression, rightExpression);
+}
+
+template<typename ArgumentType>
+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<typename ColumnData, const char* Relation>
+class __attribute__ ((visibility("hidden"))) Compare : public ExpressionWithArgument<typename ColumnData::ColumnType> {
+public:
+    explicit Compare(typename ColumnData::ColumnType column) :
+        ExpressionWithArgument<typename ColumnData::ColumnType>(column)
+    {}
+
+    virtual std::string GetString() const
+    {
+        std::string statement;
+        statement += ColumnData::GetTableName();
+        statement += ".";
+        statement += ColumnData::GetColumnName();
+        statement += " ";
+        statement += Relation;
+        statement += " ?";
+        return statement;
+    }
+
+    template<typename TableDefinition>
+    struct ValidForTable {
+        typedef typename TableDefinition::ColumnList::template Contains<ColumnData> Yes;
+    };
+};
+#define ORM_DEFINE_COMPARE_EXPRESSION(name, relationType)                      \
+    template<typename ColumnData>                                              \
+    class __attribute__ ((visibility("hidden"))) name : public Compare<ColumnData, RelationTypes::relationType> {     \
+    public:                                                                    \
+        name(typename ColumnData::ColumnType column) :                         \
+            Compare<ColumnData, RelationTypes::relationType>(column)           \
+        {}                                                                     \
+    };
+
+ORM_DEFINE_COMPARE_EXPRESSION(Equals, Equal)
+ORM_DEFINE_COMPARE_EXPRESSION(Is, Is)
+
+#define ORM_DEFINE_ORDERING_EXPRESSION(name, value)                                     \
+    template<typename ColumnType>                                                       \
+    class __attribute__ ((visibility("hidden"))) name                                   \
+        : OrderingExpression<ColumnType> {                                              \
+    public:                                                                             \
+        static std::string GetString()                                                  \
+        {                                                                               \
+            std::string statement = OrderingExpression<ColumnType>::GetSchemaAndName(); \
+            statement += value;                                                         \
+            return statement;                                                           \
+        }                                                                               \
+    };
+
+ORM_DEFINE_ORDERING_EXPRESSION(OrderingAscending, "ASC")
+ORM_DEFINE_ORDERING_EXPRESSION(OrderingDescending, "DESC")
+
+template<typename ColumnData1, typename ColumnData2>
+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<typename ColumnData1, typename ColumnData2>
+CompareBinaryColumn<ColumnData1, ColumnData2>
+    Equal()
+{
+    return CompareBinaryColumn<ColumnData1, ColumnData2>(RelationTypes::Equal);
+}
+
+template<typename ColumnData, const char* Relation>
+class __attribute__ ((visibility("hidden"))) NumerousArguments : public Expression {
+protected:
+    std::set<typename ColumnData::ColumnType> m_argumentList;
+public:
+    NumerousArguments(const std::set<typename ColumnData::ColumnType>& 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<typename TableDefinition>
+    struct ValidForTable {
+        typedef typename TableDefinition::ColumnList::template Contains<ColumnData> Yes;
+    };
+};
+
+#define ORM_DEFINE_COMPARE_EXPRESSION_NUMEROUS_ARGUMENTS(name, relationType)                      \
+    template<typename ColumnData>                                              \
+    class __attribute__ ((visibility("hidden"))) name : public NumerousArguments<ColumnData, RelationTypes::relationType> {     \
+    public:                                                                    \
+        name(std::set<typename ColumnData::ColumnType> column) :                         \
+            NumerousArguments<ColumnData, RelationTypes::relationType>(column)           \
+        {}                                                                     \
+    };
+
+ORM_DEFINE_COMPARE_EXPRESSION_NUMEROUS_ARGUMENTS(In, In)
+
+template<typename ColumnType>
+ColumnType GetColumnFromCommand(ColumnIndex columnIndex, DataCommand *command);
+
+class __attribute__ ((visibility("hidden"))) CustomColumnBase {
+public:
+    CustomColumnBase() {}
+    virtual ~CustomColumnBase() {}
+};
+
+template<typename ColumnType>
+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<typename ColumnList>
+class __attribute__ ((visibility("hidden"))) CustomRowUtil {
+public:
+    static void MakeColumnList(std::vector<CustomColumnBase*>& columnList)
+    {
+        typedef CustomColumn<typename ColumnList::Head::ColumnType> Type;
+        Type* pColumn = new Type();
+        columnList.push_back(pColumn);
+        CustomRowUtil<typename ColumnList::Tail>::MakeColumnList(columnList);
+    }
+
+    static void CopyColumnList(const std::vector<CustomColumnBase*>& srcList, std::vector<CustomColumnBase*>& dstList)
+    {
+        CopyColumnList(srcList, dstList, 0);
+    }
+
+    static ColumnIndex GetColumnIndex(const std::string& columnName)
+    {
+        return GetColumnIndex(columnName, 0);
+    }
+
+private:
+    static void CopyColumnList(const std::vector<CustomColumnBase*>& srcList, std::vector<CustomColumnBase*>& dstList, ColumnIndex index)
+    {
+        typedef CustomColumn<typename ColumnList::Head::ColumnType> Type;
+        Type* pColumn = new Type(((Type*)(srcList.at(index)))->GetColumnData());
+        dstList.push_back(pColumn);
+        CustomRowUtil<typename ColumnList::Tail>::CopyColumnList(srcList, dstList, index + 1);
+    }
+
+    static ColumnIndex GetColumnIndex(const std::string& columnName, ColumnIndex index)
+    {
+        if (ColumnList::Head::GetColumnName() == columnName)
+            return index;
+
+        return CustomRowUtil<typename ColumnList::Tail>::GetColumnIndex(columnName, index + 1);
+    }
+
+template<typename Other>
+friend class CustomRowUtil;
+};
+
+template<>
+class __attribute__ ((visibility("hidden"))) CustomRowUtil<DPL::TypeListGuard> {
+public:
+    static void MakeColumnList(std::vector<CustomColumnBase*>&) {}
+private:
+    static void CopyColumnList(const std::vector<CustomColumnBase*>&, std::vector<CustomColumnBase*>&, ColumnIndex) {}
+    static ColumnIndex GetColumnIndex(const std::string&, ColumnIndex) { return -1; }
+
+template<typename Other>
+friend class CustomRowUtil;
+};
+
+template<typename ColumnList>
+class __attribute__ ((visibility("hidden"))) CustomRow {
+private:
+    std::vector<CustomColumnBase*> m_columns;
+
+public:
+    CustomRow()
+    {
+        CustomRowUtil<ColumnList>::MakeColumnList(m_columns);
+    }
+
+    CustomRow(const CustomRow& r)
+    {
+        CustomRowUtil<ColumnList>::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<typename ColumnType>
+    void SetColumnData(ColumnIndex columnIndex, ColumnType data)
+    {
+        typedef CustomColumn<ColumnType> Type;
+        Assert(columnIndex < m_columns.size());
+        Type* pColumn = dynamic_cast<Type*>(m_columns.at(columnIndex));
+        Assert(pColumn);
+        pColumn->SetColumnData(data);
+    }
+
+    template<typename ColumnData>
+    typename ColumnData::ColumnType GetColumnData()
+    {
+        typedef CustomColumn<typename ColumnData::ColumnType> Type;
+        ColumnIndex index = CustomRowUtil<ColumnList>::GetColumnIndex(ColumnData::GetColumnName());
+        Assert(index < m_columns.size());
+        Type* pColumn = dynamic_cast<Type*>(m_columns.at(index));
+        Assert(pColumn);
+        return pColumn->GetColumnData();
+    }
+};
+
+template<typename CustomRow, typename ColumnType>
+void SetColumnData(CustomRow& row, ColumnType columnData, ColumnIndex columnIndex)
+{
+    row.SetColumnData<ColumnType>(columnIndex, columnData);
+}
+
+template<typename ColumnList, typename CustomRow>
+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<typename ColumnList::Head::ColumnType>(columnIndex, command);
+        SetColumnData<CustomRow, typename ColumnList::Head::ColumnType>(row, columnData, columnIndex);
+        FillCustomRowUtil<typename ColumnList::Tail, CustomRow>::FillCustomRow(row, columnIndex + 1, command);
+    }
+
+template<typename Other, typename OtherRow>
+friend class FillCustomRowUtil;
+};
+
+template<typename CustomRow>
+class  __attribute__ ((visibility("hidden"))) FillCustomRowUtil<DPL::TypeListGuard, CustomRow> {
+private:
+    static void FillCustomRow(CustomRow&, ColumnIndex, DataCommand *)
+    { /* do nothing, we're past the last element of column list */ }
+
+template<typename Other, typename OtherRow>
+friend class FillCustomRowUtil;
+};
+
+template<typename ColumnList, typename Row>
+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<typename ColumnList::Head::ColumnType>(columnIndex, command);
+        ColumnList::Head::SetRowField(row, rowField);
+        FillRowUtil<typename ColumnList::Tail, Row>::FillRow(row, columnIndex + 1, command);
+    }
+
+template<typename Other, typename OtherRow>
+friend class FillRowUtil;
+};
+
+template<typename Row>
+class  __attribute__ ((visibility("hidden"))) FillRowUtil<DPL::TypeListGuard, Row> {
+private:
+    static void FillRow(Row&, ColumnIndex, DataCommand *)
+    { /* do nothing, we're past the last element of column list */ }
+
+template<typename Other, typename OtherRow>
+friend class FillRowUtil;
+};
+
+template<typename ColumnList>
+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<typename ColumnList::Tail>::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<typename ColumnList::Tail>::GetJoinTableName(tableName);
+    }
+};
+
+template<>
+class  __attribute__ ((visibility("hidden"))) JoinUtil<DPL::TypeListGuard> {
+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<typename TableDefinition>
+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<typename TableDefinition>
+class  __attribute__ ((visibility("hidden"))) QueryWithWhereClause : public Query<TableDefinition>
+{
+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<TableDefinition>(interface)
+    {
+    }
+
+    template<typename Expression>
+    void Where(const Expression& expression)
+    {
+        DPL_CHECK_TYPE_INSTANTIABILITY(typename Expression::template ValidForTable<TableDefinition>::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<typename TableDefinition>
+class  __attribute__ ((visibility("hidden"))) Delete : public QueryWithWhereClause<TableDefinition>
+{
+protected:
+    void Prepare()
+    {
+        if ( !this->m_command)
+        {
+            this->m_commandString  = "DELETE FROM ";
+            this->m_commandString += TableDefinition::GetName();
+
+            QueryWithWhereClause<TableDefinition>::Prepare();
+
+            this->m_command = TableDefinition::AllocTableDataCommand(
+                    this->m_commandString.c_str(),
+                    Query<TableDefinition>::m_interface);
+            LogPedantic("Prepared SQL command " << this->m_commandString);
+        }
+    }
+
+    void Bind()
+    {
+        this->m_bindArgumentIndex = 1;
+        QueryWithWhereClause<TableDefinition>::Bind();
+    }
+
+public:
+    explicit Delete(IOrmInterface *interface = NULL) :
+        QueryWithWhereClause<TableDefinition>(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<typename ColumnType>
+    void Visit(const char*, const ColumnType& value, bool isSet)
+    {
+        if ( isSet )
+        {
+            DataCommandUtils::BindArgument(m_command, m_bindArgumentIndex, value);
+            m_bindArgumentIndex++;
+        }
+    }
+};
+} //anonymous namespace
+template<typename TableDefinition>
+class __attribute__ ((visibility("hidden"))) Insert : public Query<TableDefinition>
+{
+public:
+    typedef typename TableDefinition::Row Row;
+    typedef DPL::DB::SqlConnection::RowID RowID;
+
+protected:
+    DPL::Optional<std::string> m_orClause;
+    Row m_row;
+
+    class PrepareVisitor {
+    public:
+        std::string m_columnNames;
+        std::string m_values;
+
+        template<typename ColumnType>
+        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<TableDefinition>::m_interface);
+        }
+    }
+
+    void Bind()
+    {
+        BindVisitor visitor(this->m_command);
+        m_row.VisitColumns(visitor);
+    }
+
+public:
+    explicit Insert(
+            IOrmInterface* interface = NULL,
+            const DPL::Optional<std::string>& orClause = DPL::Optional<std::string>::Null) :
+        Query<TableDefinition>(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<TableDefinition>::m_interface);
+
+        this->m_command->Reset();
+        return result;
+    }
+};
+
+template<typename TableDefinition>
+class __attribute__ ((visibility("hidden"))) Select : public QueryWithWhereClause<TableDefinition>
+{
+public:
+    typedef typename TableDefinition::ColumnList       ColumnList;
+    typedef typename TableDefinition::Row              Row;
+
+    typedef std::list<Row>                             RowList;
+protected:
+    DPL::Optional<std::string> 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<TableDefinition>::Prepare();
+
+            if ( !m_orderBy.IsNull() )
+            {
+                this->m_commandString += " ORDER BY " + *m_orderBy;
+            }
+
+            this->m_command = TableDefinition::AllocTableDataCommand(
+                this->m_commandString.c_str(),
+                Query<TableDefinition>::m_interface);
+
+            LogPedantic("Prepared SQL command " << this->m_commandString);
+        }
+    }
+
+    void Bind()
+    {
+        this->m_bindArgumentIndex = 1;
+        QueryWithWhereClause<TableDefinition>::Bind();
+    }
+
+    template<typename ColumnType>
+    ColumnType GetColumn(ColumnIndex columnIndex)
+    {
+        return GetColumnFromCommand<ColumnType>(columnIndex, this->m_command);
+    }
+
+    Row GetRow()
+    {
+        Row row;
+        FillRowUtil<ColumnList, Row>::FillRow(row, this->m_command);
+        return row;
+    }
+
+    template<typename ColumnList, typename CustomRow>
+    CustomRow GetCustomRow()
+    {
+        CustomRow row;
+        FillCustomRowUtil<ColumnList, CustomRow>::FillCustomRow(row, this->m_command);
+        return row;
+    }
+
+public:
+
+    explicit Select(IOrmInterface *interface = NULL) :
+        QueryWithWhereClause<TableDefinition>(interface),
+        m_distinctResults(false)
+    {
+    }
+
+    void Distinct()
+    {
+        m_distinctResults = true;
+    }
+
+    template<typename CompoundType>
+    void OrderBy(const CompoundType&)
+    {
+        m_orderBy = OrderingUtils::OrderByInternal<typename CompoundType::Type>();
+    }
+
+    void OrderBy(const std::string & orderBy) //backward compatibility
+    {
+        m_orderBy = orderBy;
+    }
+
+    void OrderBy(const char * orderBy) //backward compatibility
+    {
+        m_orderBy = std::string(orderBy);
+    }
+
+    template<typename ColumnList, typename Expression>
+    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<ColumnList>::GetJoinTableName(usedTableNames);
+        this->m_JoinClause += " ON ";
+        this->m_JoinClause += expression.GetString();
+    }
+
+    template<typename ColumnData>
+    typename ColumnData::ColumnType GetSingleValue()
+    {
+        Prepare(ColumnData::GetColumnName());
+        Bind();
+        this->m_command->Step();
+
+        typename ColumnData::ColumnType result =
+            GetColumn<typename ColumnData::ColumnType>(0);
+
+        this->m_command->Reset();
+        return result;
+    }
+
+    //TODO return range - pair of custom iterators
+    template<typename ColumnData>
+    std::list<typename ColumnData::ColumnType> GetValueList()
+    {
+        Prepare(ColumnData::GetColumnName());
+        Bind();
+
+        std::list<typename ColumnData::ColumnType> resultList;
+
+        while (this->m_command->Step())
+            resultList.push_back(GetColumn<typename ColumnData::ColumnType>(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<typename ColumnList, typename CustomRow>
+    CustomRow GetCustomSingleRow()
+    {
+        Prepare(JoinUtil<ColumnList>::GetColumnNames().c_str());
+        Bind();
+        this->m_command->Step();
+
+        CustomRow result = GetCustomRow<ColumnList, CustomRow>();
+
+        this->m_command->Reset();
+        return result;
+    }
+
+    template<typename ColumnList, typename CustomRow>
+    std::list<CustomRow> GetCustomRowList()
+    {
+        Prepare(JoinUtil<ColumnList>::GetColumnNames().c_str());
+        Bind();
+
+        std::list<CustomRow> resultList;
+
+        while (this->m_command->Step())
+            resultList.push_back(GetCustomRow<ColumnList, CustomRow>());
+
+        this->m_command->Reset();
+        return resultList;
+    }
+};
+
+template<typename TableDefinition>
+class __attribute__ ((visibility("hidden"))) Update : public QueryWithWhereClause<TableDefinition> {
+public:
+    typedef typename TableDefinition::Row Row;
+
+protected:
+    DPL::Optional<std::string> m_orClause;
+    Row m_row;
+
+    class PrepareVisitor {
+    public:
+        std::string m_setExpressions;
+
+        template<typename ColumnType>
+        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<TableDefinition>::Prepare();
+
+            this->m_command = TableDefinition::AllocTableDataCommand(
+                    this->m_commandString.c_str(),
+                    Query<TableDefinition>::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<TableDefinition>::Bind();
+    }
+
+
+public:
+    explicit Update(IOrmInterface *interface = NULL,
+                    const DPL::Optional<std::string>& orClause = DPL::Optional<std::string>::Null) :
+        QueryWithWhereClause<TableDefinition>(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 (file)
index 0000000..8bd9fdb
--- /dev/null
@@ -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 <dpl/db/orm_interface.h>
+
+#define ORM_GENERATOR_DATABASE_NAME_LOCAL <ORM_GENERATOR_DATABASE_NAME>
+
+#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 <dpl/string.h>
+#include <dpl/optional.h>
+#include <dpl/type_list.h>
+#include <dpl/db/sql_connection.h>
+#include <dpl/db/orm.h>
+#include <dpl/assert.h>
+#include <string>
+
+/*
+
+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<typename Visitor>                                    \
+    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<TableDefinition> Select; \
+        typedef Insert<TableDefinition> Insert; \
+        typedef Delete<TableDefinition> Delete; \
+        typedef Update<TableDefinition> 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 (file)
index 0000000..62ec073
--- /dev/null
@@ -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 <string>
+#include <dpl/db/sql_connection.h>
+
+#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 (file)
index 0000000..a038523
--- /dev/null
@@ -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 (file)
index 0000000..d1eab36
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <dpl/optional.h>
+#include <dpl/availability.h>
+#include <memory>
+#include <dpl/string.h>
+#include <dpl/log/log.h>
+#include <sqlite3.h>
+#include <string>
+#include <dpl/assert.h>
+#include <memory>
+#include <stdint.h>
+
+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<int> &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<int8_t> &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<int16_t> &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<int32_t> &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<int64_t> &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<float> &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<double> &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<String> &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<int> GetColumnOptionalInteger(ColumnIndex column);
+
+        /**
+         * Get optional int8 value from column in current row.
+         *
+         * @throw Exception::InvalidColumn
+         */
+        Optional<int8_t> GetColumnOptionalInt8(ColumnIndex column);
+
+        /**
+         * Get optional int16value from column in current row.
+         *
+         * @throw Exception::InvalidColumn
+         */
+        Optional<int16_t> GetColumnOptionalInt16(ColumnIndex column);
+
+        /**
+         * Get optional int32 value from column in current row.
+         *
+         * @throw Exception::InvalidColumn
+         */
+        Optional<int32_t> GetColumnOptionalInt32(ColumnIndex column);
+
+        /**
+         * Get optional int64 value from column in current row.
+         *
+         * @throw Exception::InvalidColumn
+         */
+        Optional<int64_t> GetColumnOptionalInt64(ColumnIndex column);
+
+        /**
+         * Get optional float value from column in current row.
+         *
+         * @throw Exception::InvalidColumn
+         */
+        Optional<float> GetColumnOptionalFloat(ColumnIndex column);
+
+        /**
+         * Get optional double value from column in current row.
+         *
+         * @throw Exception::InvalidColumn
+         */
+        Optional<double> GetColumnOptionalDouble(ColumnIndex column);
+
+        /**
+         * Get optional string value from column in current row.
+         *
+         * @throw Exception::InvalidColumn
+         */
+        Optional<String> GetColumnOptionalString(ColumnIndex column);
+    };
+
+    // Move on copy semantics
+    typedef std::auto_ptr<DataCommand> 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<SynchronizationObject> 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 (file)
index 0000000..04ec923
--- /dev/null
@@ -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 <string>
+#include <dpl/db/sql_connection.h>
+#include <dpl/db/orm_interface.h>
+#include <dpl/thread.h>
+#include <dpl/assert.h>
+#include <stdint.h>
+
+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<SqlConnectionPtr> TLVSqlConnectionPtr;
+    typedef DPL::ThreadLocalVariable<size_t> TLVSizeT;
+    typedef DPL::ThreadLocalVariable<bool> 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 (file)
index 0000000..1ac71ca
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/db/naive_synchronization_object.h>
+#include <dpl/thread.h>
+
+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 (file)
index 0000000..c69415d
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/db/orm.h>
+
+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<int>(ColumnIndex columnIndex,
+                              DataCommand *command)
+{
+    return command->GetColumnInteger(columnIndex);
+}
+
+template<>
+DPL::String GetColumnFromCommand<DPL::String>(ColumnIndex columnIndex,
+                                              DataCommand *command)
+{
+    return DPL::FromUTF8String(command->GetColumnString(columnIndex));
+}
+
+template<>
+OptionalInteger GetColumnFromCommand<OptionalInteger>(ColumnIndex columnIndex,
+                                                      DataCommand *command)
+{
+    return command->GetColumnOptionalInteger(columnIndex);
+}
+
+template<>
+OptionalString GetColumnFromCommand<OptionalString>(ColumnIndex columnIndex,
+                                                    DataCommand *command)
+{
+    return command->GetColumnOptionalString(columnIndex);
+}
+
+template<>
+double GetColumnFromCommand<double>(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 (file)
index 0000000..60c6621
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/db/sql_connection.h>
+#include <dpl/db/naive_synchronization_object.h>
+#include <dpl/scoped_free.h>
+#include <dpl/noncopyable.h>
+#include <dpl/assert.h>
+#include <db-util.h>
+#include <unistd.h>
+#include <cstdio>
+#include <cstdarg>
+
+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<int>(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<int>(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<int>(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<sqlite3_int64>(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<double>(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<int> &value)
+{
+    if (value.IsNull()) {
+        BindNull(position);
+    } else {
+        BindInteger(position, *value);
+    }
+}
+
+void SqlConnection::DataCommand::BindInt8(
+    SqlConnection::ArgumentIndex position,
+    const Optional<int8_t> &value)
+{
+    if (value.IsNull()) {
+        BindNull(position);
+    } else {
+        BindInt8(position, *value);
+    }
+}
+
+void SqlConnection::DataCommand::BindInt16(
+    SqlConnection::ArgumentIndex position,
+    const Optional<int16_t> &value)
+{
+    if (value.IsNull()) {
+        BindNull(position);
+    } else {
+        BindInt16(position, *value);
+    }
+}
+
+void SqlConnection::DataCommand::BindInt32(
+    SqlConnection::ArgumentIndex position,
+    const Optional<int32_t> &value)
+{
+    if (value.IsNull()) {
+        BindNull(position);
+    } else {
+        BindInt32(position, *value);
+    }
+}
+
+void SqlConnection::DataCommand::BindInt64(
+    SqlConnection::ArgumentIndex position,
+    const Optional<int64_t> &value)
+{
+    if (value.IsNull()) {
+        BindNull(position);
+    } else {
+        BindInt64(position, *value);
+    }
+}
+
+void SqlConnection::DataCommand::BindFloat(
+    SqlConnection::ArgumentIndex position,
+    const Optional<float> &value)
+{
+    if (value.IsNull()) {
+        BindNull(position);
+    } else {
+        BindFloat(position, *value);
+    }
+}
+
+void SqlConnection::DataCommand::BindDouble(
+    SqlConnection::ArgumentIndex position,
+    const Optional<double> &value)
+{
+    if (value.IsNull()) {
+        BindNull(position);
+    } else {
+        BindDouble(position, *value);
+    }
+}
+
+void SqlConnection::DataCommand::BindString(
+    SqlConnection::ArgumentIndex position,
+    const Optional<String> &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<int8_t>(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<int16_t>(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<int32_t>(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<int64_t>(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<float>(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<const char *>(
+            sqlite3_column_text(m_stmt, column));
+
+    LogPedantic("Value: " << (value ? value : "NULL"));
+
+    if (value == NULL) {
+        return std::string();
+    }
+
+    return std::string(value);
+}
+
+Optional<int> 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<int>::Null;
+    }
+    int value = sqlite3_column_int(m_stmt, column);
+    LogPedantic("    Value: " << value);
+    return Optional<int>(value);
+}
+
+Optional<int8_t> 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<int8_t>::Null;
+    }
+    int8_t value = static_cast<int8_t>(sqlite3_column_int(m_stmt, column));
+    LogPedantic("    Value: " << value);
+    return Optional<int8_t>(value);
+}
+
+Optional<int16_t> 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<int16_t>::Null;
+    }
+    int16_t value = static_cast<int16_t>(sqlite3_column_int(m_stmt, column));
+    LogPedantic("    Value: " << value);
+    return Optional<int16_t>(value);
+}
+
+Optional<int32_t> 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<int32_t>::Null;
+    }
+    int32_t value = static_cast<int32_t>(sqlite3_column_int(m_stmt, column));
+    LogPedantic("    Value: " << value);
+    return Optional<int32_t>(value);
+}
+
+Optional<int64_t> 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<int64_t>::Null;
+    }
+    int64_t value = static_cast<int64_t>(sqlite3_column_int64(m_stmt, column));
+    LogPedantic("    Value: " << value);
+    return Optional<int64_t>(value);
+}
+
+Optional<float> 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<float>::Null;
+    }
+    float value = static_cast<float>(sqlite3_column_double(m_stmt, column));
+    LogPedantic("    Value: " << value);
+    return Optional<float>(value);
+}
+
+Optional<double> 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<double>::Null;
+    }
+    double value = sqlite3_column_double(m_stmt, column);
+    LogPedantic("    Value: " << value);
+    return Optional<double>(value);
+}
+
+Optional<String> 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<String>::Null;
+    }
+    const char *value = reinterpret_cast<const char *>(
+            sqlite3_column_text(m_stmt, column));
+    LogPedantic("Value: " << value);
+    String s = FromUTF8String(value);
+    return Optional<String>(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="<<result);
+            if( retry-- <= 0 )
+                ThrowMsg(Exception::ConnectionBroken, address);
+        }
+    }
+
+    // Enable foreign keys
+    TurnOnForeignKeys();
+}
+
+void SqlConnection::Disconnect()
+{
+    if (m_connection == NULL) {
+        LogPedantic("Already disconnected.");
+        return;
+    }
+
+    LogPedantic("Disconnecting from DB...");
+
+    // All stored data commands must be deleted before disconnect
+    AssertMsg(m_dataCommandsCount == 0,
+           "All stored procedures must be deleted"
+           " before disconnecting SqlConnection");
+
+    int result;
+
+    if (m_usingLucene) {
+        result = db_util_close(m_connection);
+    } else {
+        result = sqlite3_close(m_connection);
+    }
+
+    if (result != SQLITE_OK) {
+        const char *error = sqlite3_errmsg(m_connection);
+        LogPedantic("SQL close failed");
+        LogPedantic("    Error: " << error);
+        Throw(Exception::InternalError);
+    }
+
+    m_connection = NULL;
+
+    LogPedantic("Disconnected from DB");
+}
+
+bool SqlConnection::CheckTableExist(const char *tableName)
+{
+    if (m_connection == NULL) {
+        LogPedantic("Cannot execute command. Not connected to DB!");
+        return false;
+    }
+
+    DataCommandAutoPtr command =
+        PrepareDataCommand("select tbl_name from sqlite_master where name=?;");
+
+    command->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<char> 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<char> 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<RowID>(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 (file)
index 0000000..101640f
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/db/thread_database_support.h>
\ No newline at end of file
diff --git a/modules/dbus/config.cmake b/modules/dbus/config.cmake
new file mode 100644 (file)
index 0000000..f2fefde
--- /dev/null
@@ -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 (file)
index 0000000..4a455ad
--- /dev/null
@@ -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 <memory>
+#include <vector>
+#include <string>
+#include <dpl/generic_event.h>
+#include <dpl/event/event_support.h>
+#include <dpl/dbus/object.h>
+#include <dpl/dbus/object_proxy.h>
+#include <dpl/dbus/glib_util.h>
+
+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<Connection> ConnectionPtr;
+
+typedef std::shared_ptr<ObjectProxy> ObjectProxyPtr;
+
+class Connection :
+    public DPL::Event::EventSupport<ConnectionEvents::ServiceNameAcquiredEvent>,
+    public DPL::Event::EventSupport<ConnectionEvents::ServiceNameLostEvent>,
+    public DPL::Event::EventSupport<ConnectionEvents::ConnectionBrokenEvent>,
+    public DPL::Event::EventSupport<ConnectionEvents::ConnectionInvalidEvent>
+{
+  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<std::string, guint> RegisteredServices;
+
+    struct ObjectRegistration
+    {
+        ObjectRegistration(guint _registrationId, const ObjectPtr& _object) :
+            registrationId(_registrationId),
+            object(_object)
+        {}
+
+        guint registrationId;
+        ObjectPtr object;
+    };
+    typedef std::map<std::string, ObjectRegistration> 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 (file)
index 0000000..061ec46
--- /dev/null
@@ -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 <string>
+#include <dbus/dbus.h>
+#include <dpl/exception.h>
+#include <dpl/log/log.h>
+#include <dpl/dbus/dbus_serialization.h>
+#include <dpl/dbus/dbus_deserialization.h>
+
+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<typename ... Args>
+    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<typename ... Args>
+    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<typename T, typename ... Args>
+    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<typename T, typename ... Args>
+    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<typename T, typename ... Args>
+    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<typename T, typename ... Args>
+    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<typename T, typename ... Args>
+    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<typename T>
+    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 (file)
index 0000000..2a05db8
--- /dev/null
@@ -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 <map>
+#include <vector>
+#include <list>
+#include <set>
+#include <string>
+#include <dbus/dbus.h>
+#include <dpl/dbus/dbus_signature.h>
+
+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<typename T>
+    static bool deserialize(DBusMessageIter* responseIterator, T* arg)
+    {
+        if (dbus_message_iter_get_arg_type(responseIterator)
+            != SimpleType<T>::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<float>(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<typename T>
+    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<typename T>
+    static bool deserialize(
+        DBusMessageIter* responseIterator,
+        std::vector<T>* arg)
+    {
+        return deserializeContainer(responseIterator, arg);
+    }
+
+    // std::list
+    template<typename T>
+    static bool deserialize(
+        DBusMessageIter* responseIterator,
+        std::list<T>* arg)
+    {
+        return deserializeContainer(responseIterator, arg);
+    }
+
+    // std::set
+    template<typename T>
+    static bool deserialize(
+        DBusMessageIter* responseIterator,
+        std::set<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)
+        {
+            typename std::set<T>::value_type element;
+            if (!deserialize(&subIterator, &element)) {
+                return false;
+            }
+            arg->insert(element);
+            dbus_message_iter_next(&subIterator);
+        }
+        return true;
+    }
+
+    // std::pair
+    template<typename A, typename B>
+    static bool deserialize(
+        DBusMessageIter* argsIterator,
+        const std::pair<A, B>* 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<typename K, typename V>
+    static bool deserialize(
+        DBusMessageIter* responseIterator,
+        const std::map<K, V>* 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<K, V> element;
+            if (!deserialize(&subIterator, &element)) {
+                return false;
+            }
+            arg->insert(element);
+            dbus_message_iter_next(&subIterator);
+        }
+        return true;
+    }
+};
+
+template<>
+inline bool Deserialization::deserialize<bool>(
+    DBusMessageIter* responseIterator,
+    bool* arg)
+{
+    unsigned int value;
+    if (dbus_message_iter_get_arg_type(responseIterator)
+        != SimpleType<bool>::value)
+    {
+        return false;
+    }
+    dbus_message_iter_get_basic(responseIterator, &value);
+    *arg = static_cast<bool>(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 (file)
index 0000000..97d7407
--- /dev/null
@@ -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 <string>
+#include <dpl/log/log.h>
+#include <dpl/dbus/dispatcher.h>
+
+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 (file)
index 0000000..c0fa338
--- /dev/null
@@ -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 <map>
+#include <vector>
+#include <list>
+#include <set>
+#include <string>
+#include <dbus/dbus.h>
+#include <dpl/foreach.h>
+#include <dpl/dbus/dbus_signature.h>
+
+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<double>(arg);
+        return serialize(argsIterator, d);
+    }
+
+    // char* and all integer types + doubles
+    template<typename T>
+    static bool serialize(DBusMessageIter* argsIterator, const T& arg)
+    {
+        return dbus_message_iter_append_basic(argsIterator,
+                                              SimpleType<T>::value,
+                                              &arg);
+    }
+
+    // dbus array serialization
+    template<typename T>
+    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<typename T::value_type>
+                                                  ::value(), &subIterator))
+        {
+            return false;
+        }
+        FOREACH(containerIt, arg) {
+            if (!serialize(&subIterator, *containerIt)) {
+                return false;
+            }
+        }
+        return dbus_message_iter_close_container(argsIterator, &subIterator);
+    }
+
+    // std::vector
+    template<typename T>
+    static bool serialize(
+        DBusMessageIter* argsIterator,
+        const std::vector<T> &arg)
+    {
+        return serializeContainer(argsIterator, arg);
+    }
+
+    // std::list
+    template<typename T>
+    static bool serialize(
+        DBusMessageIter* argsIterator,
+        const std::list<T> &arg)
+    {
+        return serializeContainer(argsIterator, arg);
+    }
+
+    // std::set
+    template<typename T>
+    static bool serialize(
+        DBusMessageIter* argsIterator,
+        const std::set<T> &arg)
+    {
+        return serializeContainer(argsIterator, arg);
+    }
+
+    // std::pair
+    template<typename A, typename B>
+    static bool serialize(
+        DBusMessageIter* argsIterator,
+        const std::pair<A, B> &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<typename K, typename V>
+    static bool serialize(
+        DBusMessageIter* argsIterator,
+        const std::map<K, V> &arg)
+    {
+        return serializeContainer(argsIterator, arg);
+    }
+};
+
+// char* and all integer types + doubles
+template<>
+inline bool Serialization::serialize<bool>(DBusMessageIter* argsIterator,
+                                           const bool& arg)
+{
+    unsigned int value = static_cast<unsigned int>(arg);
+    return dbus_message_iter_append_basic(argsIterator,
+                                          SimpleType<bool>::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 (file)
index 0000000..eb09d6d
--- /dev/null
@@ -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 <string>
+#include <vector>
+#include <list>
+#include <map>
+#include <gio/gio.h>
+#include <dpl/assert.h>
+
+namespace DPL {
+namespace DBus {
+struct ServerDeserialization {
+    template<typename T, typename ... Args>
+    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<typename T>
+    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<typename T, typename ... Args>
+    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<typename T>
+    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<float>(arg);
+        return true;
+    }
+
+    static bool deserializeElem(GVariant* parameters,
+                                std::vector<std::string>* 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<std::string>* 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 (file)
index 0000000..9e47ca6
--- /dev/null
@@ -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 <string>
+#include <gio/gio.h>
+
+namespace DPL {
+namespace DBus {
+struct ServerSerialization {
+    template<typename ... Args>
+    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<typename T, typename ... Args>
+    static void serializeBuilder(GVariantBuilder* builder,
+                                 const T& arg,
+                                 Args ... args)
+    {
+        serializeElem(builder, arg);
+        serializeBuilder(builder, args ...);
+    }
+
+    template<typename T>
+    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<gdouble>(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 (file)
index 0000000..bc99108
--- /dev/null
@@ -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 <dbus/dbus.h>
+#include <string>
+
+namespace DPL {
+namespace DBus {
+template<typename T>
+struct SimpleType;
+
+template<typename T>
+struct Signature
+{
+    static inline const char* value()
+    {
+        static const char signature[] =
+        { (char) SimpleType<T>::value, 0 };
+        return signature;
+    }
+};
+
+// signed integer types
+template<int size>
+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<int size>
+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<bool>
+{
+    static const int value = DBUS_TYPE_BOOLEAN;
+};
+
+template<>
+struct SimpleType<char>
+{
+    static const int value = __UnsignedIntegerType<sizeof(char)>::value;
+};
+
+template<>
+struct SimpleType<signed char>
+{
+    static const int value = __SignedIntegerType<sizeof(signed char)>::value;
+};
+
+template<>
+struct SimpleType<unsigned char>
+{
+    static const int value =
+        __UnsignedIntegerType<sizeof(unsigned char)>::value;
+};
+
+template<>
+struct SimpleType<short>
+{
+    static const int value = __SignedIntegerType<sizeof(short)>::value;
+};
+
+template<>
+struct SimpleType<unsigned short>
+{
+    static const int value =
+        __UnsignedIntegerType<sizeof(unsigned short)>::value;
+};
+
+template<>
+struct SimpleType<int>
+{
+    static const int value = __SignedIntegerType<sizeof(int)>::value;
+};
+
+template<>
+struct SimpleType<unsigned int>
+{
+    static const int value =
+        __UnsignedIntegerType<sizeof(unsigned int)>::value;
+};
+
+template<>
+struct SimpleType<long>
+{
+    static const int value = __SignedIntegerType<sizeof(long)>::value;
+};
+
+template<>
+struct SimpleType<unsigned long>
+{
+    static const int value =
+        __UnsignedIntegerType<sizeof(unsigned long)>::value;
+};
+
+template<>
+struct SimpleType<long long>
+{
+    static const int value = __SignedIntegerType<sizeof(long long)>::value;
+};
+
+template<>
+struct SimpleType<unsigned long long>
+{
+    static const int value = __UnsignedIntegerType<
+            sizeof(unsigned long long)>::value;
+};
+
+template<>
+struct SimpleType<float>
+{
+    static const int value = DBUS_TYPE_DOUBLE;
+};
+
+template<>
+struct SimpleType<double>
+{
+    static const int value = DBUS_TYPE_DOUBLE;
+};
+
+template<>
+struct SimpleType<const char *>
+{
+    static const int value = DBUS_TYPE_STRING;
+};
+
+template<>
+struct SimpleType<char *>
+{
+    static const int value = DBUS_TYPE_STRING;
+};
+
+template<>
+struct SimpleType<std::string>
+{
+    static const int value = DBUS_TYPE_STRING;
+};
+
+// STL containers signatures
+
+// generic array
+template<typename T>
+struct ArraySignature
+{
+    static inline const char* value()
+    {
+        static const std::string signature = std::string(
+                DBUS_TYPE_ARRAY_AS_STRING) + Signature<T>::value();
+        return signature.c_str();
+    }
+};
+
+// std::vector
+template<typename T>
+struct Signature<std::vector<T> > : public ArraySignature<T>
+{};
+
+// std::list
+template<typename T>
+struct Signature<std::list<T> > : public ArraySignature<T>
+{};
+
+// std::set
+template<typename T>
+struct Signature<std::set<T> > : public ArraySignature<T>
+{};
+
+// std::pair
+template<typename K, typename V>
+struct Signature<std::pair<K, V> >
+{
+    static inline const char* value()
+    {
+        static const std::string signature = std::string(
+                DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING)
+            + Signature<K>::value() + Signature<V>::value()
+            + DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
+        return signature.c_str();
+    }
+};
+
+// std::map
+template<typename K, typename V>
+struct Signature<std::map<K, V> > : public ArraySignature<std::pair<K, V> >
+{};
+} // 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 (file)
index 0000000..93e62e6
--- /dev/null
@@ -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 <gio/gio.h>
+
+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 (file)
index 0000000..035d16f
--- /dev/null
@@ -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 <dpl/exception.h>
+
+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 (file)
index 0000000..13206e3
--- /dev/null
@@ -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 <gio/gio.h>
+
+#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 (file)
index 0000000..6248dab
--- /dev/null
@@ -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 <memory>
+#include <vector>
+#include <gio/gio.h>
+#include <dpl/noncopyable.h>
+#include <dpl/dbus/dispatcher.h>
+
+namespace DPL {
+namespace DBus {
+class Interface;
+typedef std::shared_ptr<Interface> 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<InterfacePtr> 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 (file)
index 0000000..19c3b90
--- /dev/null
@@ -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 <type_traits>
+#include <utility>
+#include <memory>
+#include <string>
+#include <gio/gio.h>
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/dbus/exception.h>
+#include <dpl/dbus/dbus_server_serialization.h>
+#include <dpl/dbus/dbus_server_deserialization.h>
+
+namespace DPL {
+namespace DBus {
+class ObjectProxy;
+
+/**
+ * Represents a remote method.
+ */
+template<typename Result, typename ... Args>
+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 R = Result>
+    typename std::enable_if<!std::is_void<R>::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 R = Result>
+    typename std::enable_if<std::is_void<R>::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<typename ... ArgsM>
+    GVariant* serialize(ArgsM && ... args)
+    {
+        return ServerSerialization::serialize(std::forward<ArgsM>(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<typename Result, typename ... Args>
+class MethodProxyPtr
+{
+  public:
+    explicit MethodProxyPtr(MethodProxy<Result, Args ...>* 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<MethodProxy<Result, Args ...> > 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 (file)
index 0000000..191464c
--- /dev/null
@@ -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 <memory>
+#include <string>
+#include <gio/gio.h>
+#include <dpl/dbus/interface.h>
+
+namespace DPL {
+namespace DBus {
+class Object;
+typedef std::shared_ptr<Object> 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 (file)
index 0000000..17764f1
--- /dev/null
@@ -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 <string>
+#include <gio/gio.h>
+#include <dpl/dbus/exception.h>
+#include <dpl/dbus/method_proxy.h>
+
+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<typename Result, typename ... Args>
+    MethodProxyPtr<Result, Args ...> createMethodProxy(
+        const std::string& interface,
+        const std::string& name)
+    {
+        if (g_dbus_connection_is_closed(m_connection)) {
+            ThrowMsg(DBus::ConnectionClosedException, "Connection closed.");
+        }
+
+        return MethodProxyPtr<Result, Args ...>(
+                   new MethodProxy<Result, Args ...>(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 (file)
index 0000000..795a757
--- /dev/null
@@ -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 <memory>
+#include <string>
+#include <gio/gio.h>
+#include <dpl/generic_event.h>
+#include <dpl/event/event_support.h>
+#include <dpl/dbus/connection.h>
+
+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<Server> ServerPtr;
+
+/**
+ * Class acting as a server for peer to peer connections over DBus.
+ */
+class Server : public DPL::Event::EventSupport<ServerEvents::NewConnectionEvent>
+{
+  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 (file)
index 0000000..9c3b6ba
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/log/log.h>
+#include <dpl/dbus/connection.h>
+#include <dpl/dbus/exception.h>
+#include <dpl/dbus/object_proxy.h>
+
+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<Connection*>(data);
+
+    LogPedantic("Emitting service name acquired event: " << serviceName);
+
+    ConnectionEvents::ServiceNameAcquiredEvent event(serviceName);
+    self->DPL::Event::EventSupport<ConnectionEvents::ServiceNameAcquiredEvent>
+        ::
+        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<Connection*>(data);
+
+    LogPedantic("Emitting service name lost event: " << serviceName);
+
+    ConnectionEvents::ServiceNameLostEvent event(serviceName);
+    self->DPL::Event::EventSupport<ConnectionEvents::ServiceNameLostEvent>::
+        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<Connection*>(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<ConnectionEvents::
+                                               ConnectionBrokenEvent>::
+                EmitEvent(event, DPL::Event::EmitMode::Queued);
+        } else {
+            // Invalid or malformed data on connection.
+            ConnectionEvents::ConnectionInvalidEvent event(message);
+            self->DPL::Event::EventSupport<ConnectionEvents::
+                                               ConnectionInvalidEvent>::
+                EmitEvent(event, DPL::Event::EmitMode::Queued);
+        }
+    }
+}
+}
+}
diff --git a/modules/dbus/src/dispatcher.cpp b/modules/dbus/src/dispatcher.cpp
new file mode 100644 (file)
index 0000000..d83a22a
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/dbus/dispatcher.h>
+
+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 (file)
index 0000000..b449e7c
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/dbus/exception.h>
+#include <dpl/dbus/interface.h>
+
+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<InterfacePtr> 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<InterfacePtr> 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<Interface*>(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<Interface*>(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<Interface*>(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 (file)
index 0000000..a66796d
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/dbus/object.h>
+
+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 (file)
index 0000000..9b15bb7
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/dbus/object_proxy.h>
+
+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 (file)
index 0000000..41c6962
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+#include <dpl/dbus/server.h>
+
+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<GDBusServerFlags>(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<Server*>(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<ServerEvents::NewConnectionEvent>::
+        EmitEvent(event, DPL::Event::EmitMode::Blocking);
+
+    return TRUE;
+}
+}
+}
diff --git a/modules/event/config.cmake b/modules/event/config.cmake
new file mode 100644 (file)
index 0000000..313b6a8
--- /dev/null
@@ -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 (file)
index 0000000..db1bea4
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+
+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 (file)
index 0000000..f5caa56
--- /dev/null
@@ -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 <dpl/event/abstract_event_call.h>
+#include <dpl/noncopyable.h>
+
+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 (file)
index 0000000..1b14632
--- /dev/null
@@ -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 <dpl/event/event_support.h>
+#include <dpl/event/event_listener.h>
+#include <dpl/type_list.h>
+#include <dpl/thread.h>
+#include <dpl/assert.h>
+
+namespace DPL {
+namespace Event {
+template<typename EventType>
+class ControllerEventHandler :
+    public EventListener<EventType>,
+    private EventSupport<EventType>
+{
+  private:
+    bool m_touched;
+
+  public:
+    ControllerEventHandler() :
+        m_touched(false)
+    {
+        EventSupport<EventType>::AddListener(this);
+    }
+
+    virtual ~ControllerEventHandler()
+    {
+        EventSupport<EventType>::RemoveListener(this);
+    }
+
+    void PostEvent(const EventType &event)
+    {
+        Assert(
+            m_touched &&
+            "Default context not inherited. Call Touch() to inherit one.");
+        EventSupport<EventType>::EmitEvent(event, EmitMode::Queued);
+    }
+
+    void PostTimedEvent(const EventType &event, double dueTime)
+    {
+        Assert(
+            m_touched &&
+            "Default context not inherited. Call Touch() to inherit one.");
+        EventSupport<EventType>::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<EventType>::EmitEvent(event, EmitMode::Blocking);
+    }
+
+    void SwitchToThread(Thread *thread)
+    {
+        Assert(
+            m_touched &&
+            "Default context not inherited. Call Touch() to inherit one.");
+        EventSupport<EventType>::SwitchListenerToThread(this, thread);
+    }
+
+    void Touch()
+    {
+        m_touched = true;
+        EventSupport<EventType>::SwitchListenerToThread(
+            this,
+            Thread::
+                GetCurrentThread());
+    }
+};
+
+template<typename EventTypeList>
+class Controller :
+    public Controller<typename EventTypeList::Tail>,
+    public ControllerEventHandler<typename EventTypeList::Head>
+{
+  public:
+    typedef typename EventTypeList::Head EventType;
+
+  public:
+    Controller()
+    {}
+
+    virtual ~Controller()
+    {}
+
+    virtual void SwitchToThread(Thread *thread)
+    {
+        ControllerEventHandler<EventType>::SwitchToThread(thread);
+        Controller<typename EventTypeList::Tail>::SwitchToThread(thread);
+    }
+
+    virtual void Touch()
+    {
+        ControllerEventHandler<EventType>::Touch();
+        Controller<typename EventTypeList::Tail>::Touch();
+    }
+};
+
+template<>
+class Controller<TypeListDecl<>::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 (file)
index 0000000..27fdbec
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+
+namespace DPL {
+namespace Event {
+template<typename EventType>
+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 (file)
index 0000000..e7fcaef
--- /dev/null
@@ -0,0 +1,721 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES 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 <functional>
+#include <list>
+#include <map>
+#include <memory>
+#include <type_traits>
+#include <vector>
+
+#include <dpl/event/event_listener.h>
+#include <dpl/event/abstract_event_dispatcher.h>
+#include <dpl/event/main_event_dispatcher.h>
+#include <dpl/event/thread_event_dispatcher.h>
+#include <dpl/event/generic_event_call.h>
+#include <dpl/waitable_event.h>
+#include <dpl/exception.h>
+#include <dpl/thread.h>
+#include <dpl/assert.h>
+#include <dpl/atomic.h>
+#include <dpl/mutex.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+
+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<typename EventType>
+class EventSupport :
+    private Noncopyable
+{
+  public:
+    typedef EventSupport<EventType> EventSupportType;
+
+    typedef EventListener<EventType> EventListenerType;
+
+    typedef void DelegateSignature(const EventType&);
+    typedef std::function<DelegateSignature> DelegateType;
+
+    class EventSupportData; // Forward declaration
+    typedef EventSupportData *EventSupportDataPtr;
+
+  private:
+    typedef typename GenericEventCall<EventType, EventSupportDataPtr>::
+        template Rebind<EventType, EventSupportDataPtr>::
+        Other GenericEventCallType;
+
+    // Event listener list
+    typedef std::map<EventListenerType *, Thread *> EventListenerList;
+    EventListenerList m_eventListenerList;
+
+    struct DelegateCompare
+    {
+        typedef typename std::add_pointer<DelegateSignature>::type
+            DelegateSignaturePtr;
+
+        bool operator()(const DelegateType& a, const DelegateType& b) const
+        {
+            return comparer(a.template target<DelegateSignature>(),
+                            b.template target<DelegateSignature>());
+        }
+
+        const std::less<DelegateSignaturePtr> comparer;
+    };
+
+    // Delegate list
+    typedef std::map<DelegateType, Thread *, DelegateCompare> 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<GenericEventCallType *> 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()
+        {
+            Mutex::ScopedLock lock(&m_dataMutex);
+            m_eventSupport = NULL;
+        }
+    };
+
+  private:
+    GenericEventCallType *RegisterEventCall(const EventType &event,
+                                            EventListenerType *eventListener,
+                                            DelegateType delegate,
+                                            WaitableEvent *waitableEvent)
+    {
+        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);
+
+        m_eventsList.erase(eventIterator);
+    }
+
+    // Note: Reentrant metod
+    void GuardedEventCall(const EventType &event,
+                          EventListenerType *eventListener)
+    {
+        ++m_guardedCallInProgress;
+
+        UNHANDLED_EXCEPTION_HANDLER_BEGIN
+        {
+            eventListener->OnEventReceived(event);
+        }
+        UNHANDLED_EXCEPTION_HANDLER_END
+
+        -- m_guardedCallInProgress;
+    }
+
+    // Note: Reentrant metod
+    void GuardedEventCall(const EventType &event,
+                          DelegateType delegate)
+    {
+        ++m_guardedCallInProgress;
+
+        UNHANDLED_EXCEPTION_HANDLER_BEGIN
+        {
+            delegate(event);
+        }
+        UNHANDLED_EXCEPTION_HANDLER_END
+
+        -- m_guardedCallInProgress;
+    }
+
+    void ReceiveAbstractEventCall(const EventType &event,
+                                  EventListenerType *eventListener,
+                                  DelegateType delegate,
+                                  WaitableEvent *synchronization)
+    {
+        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<Mutex::ScopedLock> lock(
+            new Mutex::ScopedLock(&m_listenerDelegateMutex));
+
+        // Show some info
+        switch (mode) {
+        case EmitMode::Auto:
+            break;
+
+        case EmitMode::Queued:
+            break;
+
+        case EmitMode::Blocking:
+            break;
+
+        case EmitMode::Deffered:
+            break;
+
+        default:
+            break;
+        }
+
+        // In some configurations there is a barrier
+        std::vector<WaitableEvent *> 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
+                dispatcher = &GetMainEventDispatcherInstance();
+            } else {
+                // Setup thread dispatcher, and send to proper thread
+                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");
+            }
+        }
+
+        // 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
+                dispatcher = &GetMainEventDispatcherInstance();
+            } else {
+                // Setup thread dispatcher, and send to proper thread
+                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");
+            }
+        }
+
+        // Leave listeners lock in case of blocking call
+        if (!synchronizationBarrier.empty()) {
+            LogPedantic("Leaving lock due to existing barrier");
+            lock.reset();
+        }
+
+        // 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<WaitableEvent *> clearedSynchronizationBarrier;
+
+            FOREACH(iterator, synchronizationBarrier)
+            {
+                if (*iterator == NULL) {
+                    continue;
+                }
+
+                clearedSynchronizationBarrier.push_back(*iterator);
+            }
+
+            synchronizationBarrier.swap(clearedSynchronizationBarrier);
+        }
+    }
+
+  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);
+
+        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()));
+    }
+
+    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()));
+    }
+
+    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);
+    }
+
+    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);
+    }
+
+    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;
+    }
+
+    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;
+    }
+
+    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;
+    }
+};
+}
+} // 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 (file)
index 0000000..2cdf026
--- /dev/null
@@ -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 <functional>
+
+#include <dpl/event/abstract_event_call.h>
+#include <dpl/event/event_listener.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+
+namespace DPL {
+namespace Event {
+template<typename EventType, typename SupportDataType>
+class GenericEventCall :
+    public AbstractEventCall
+{
+  public:
+    typedef EventListener<EventType> EventListenerType;
+    typedef std::function<void(const EventType &)> DelegateType;
+
+  protected:
+    SupportDataType m_supportData;
+    EventListenerType *m_eventListener;
+    DelegateType m_delegate;
+    EventType m_event;
+
+  public:
+    template<typename OtherEventType, typename OtherSupportType>
+    struct Rebind
+    {
+        typedef GenericEventCall<OtherEventType, OtherSupportType> 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 (file)
index 0000000..2d711fe
--- /dev/null
@@ -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 <bits/c++0x_warning.h>
+#else
+
+#include <functional>
+#include <list>
+#include <memory>
+#include <tuple>
+
+#include <dpl/event/event_support.h>
+#include <dpl/event/thread_event_dispatcher.h>
+#include <dpl/event/main_event_dispatcher.h>
+#include <dpl/generic_event.h>
+#include <dpl/foreach.h>
+#include <dpl/recursive_mutex.h>
+#include <dpl/mutex.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/apply.h>
+#include <dpl/bind.h>
+
+/*
+ * - 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<T>
+ *
+ * 2. Create instance of ICDelegate by calling
+ *    makeICDelegate and passing to it pointer to method
+ *
+ *    class A : ICDelegateSupport<A>
+ *    {
+ *    void methodA(int) {}
+ *    void createDelegate() {
+ *        ICDelegate<int> dlg;
+ *        dlg = makeICDelegate(&A::MethodA);
+ *    };
+ */
+
+namespace DPL {
+namespace Event {
+//forward declaration
+template <typename ... ArgTypesList>
+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<ICDSharedDataBase> ICDSharedDataBasePtr;
+    typedef std::list<ICDSharedDataBasePtr> 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 <typename ... ArgTypesList>
+    friend class DPL::Event::ICDelegate;
+};
+} //ICDPrivate
+
+template<typename ThisType, typename ... ArgTypesList>
+std::function<void (ArgTypesList ...)>
+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 <typename ... ArgTypesList>
+class ICDelegate
+{
+  public:
+    ICDelegate()
+    {}
+    ICDelegate(ICDPrivate::ICDelegateSupportInterface* base,
+               std::function<void (ArgTypesList ...)> 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<ICDPrivate::ICDSharedDataBase>(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<ICDPrivate::ICDSharedDataBase>(m_helper));
+        m_helper->disable();
+    }
+
+  protected:
+    ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr
+    getRelatedICDSharedData() const
+    {
+        return std::static_pointer_cast<ICDPrivate::ICDSharedDataBase>(m_helper);
+    }
+
+  private:
+    template<typename ThisType>
+    friend class ICDelegateSupport;
+    class ICDSharedData;
+    typedef std::shared_ptr<ICDSharedData> ICDSharedDataPtr;
+
+    struct PrivateEvent
+    {
+        PrivateEvent(ICDSharedDataPtr a_helper,
+                     ArgTypesList ... arguments) :
+            helper(a_helper),
+            args(std::make_tuple(arguments ...))
+        {}
+
+        ICDSharedDataPtr helper;
+        std::tuple<ArgTypesList ...> args;
+    };
+
+    typedef std::function<void (const PrivateEvent&)>
+    ICDSharedDataDelegateType;
+    class ICDSharedData : private DPL::Event::EventSupport<PrivateEvent>,
+        public std::enable_shared_from_this<ICDSharedData>,
+        public ICDPrivate::ICDSharedDataBase
+    {
+      public:
+        ICDSharedData(
+            ICDPrivate::ICDelegateSupportInterface *base,
+            std::function<void (ArgTypesList ...)> 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<PrivateEvent>::AddListener(m_subDelegate);
+        }
+
+        void CallDelegate(ArgTypesList ... args)
+        {
+            ICDPrivate::ICDSharedDataBase::ScopedLock lock(
+                std::static_pointer_cast<ICDPrivate::ICDSharedDataBase>(
+                    this->shared_from_this()));
+            if (!isDisabled()) {
+                EmitEvent(PrivateEvent(this->shared_from_this(),
+                                       args ...));
+            }
+        }
+
+        virtual void disable()
+        {
+            ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr ptr(
+                std::static_pointer_cast<ICDSharedDataBase>(
+                    this->shared_from_this()));
+            ICDPrivate::ICDSharedDataBase::ScopedLock lock(ptr);
+            if (!isDisabled()) {
+                ICDPrivate::ICDSharedDataBase::disable();
+                EventSupport<PrivateEvent>::RemoveListener(m_subDelegate);
+                m_base->unregisterICDSharedData(ptr);
+            }
+        }
+
+      private:
+        friend class std::shared_ptr<ICDSharedData>;
+        ICDSharedDataDelegateType m_subDelegate;
+        ICDPrivate::ICDelegateSupportInterface* m_base;
+        std::function<void (ArgTypesList ...)> m_outerDelegate;
+        ICD::Reuse m_reuse;
+
+        void delegateForwarder(const PrivateEvent& event)
+        {
+            ICDPrivate::ICDSharedDataBase::ICDSharedDataBasePtr ptr(
+                std::static_pointer_cast<ICDSharedDataBase>(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 <typename ThisType>
+class ICDelegateSupport : public ICDPrivate::ICDelegateSupportInterface
+{
+  protected:
+    template<typename ... ArgTypesList>
+    ICDelegate<ArgTypesList ...> makeICDelegate(
+        void (ThisType::*Func)(ArgTypesList ...),
+        ICD::Reuse reuse = ICD::Reuse::No)
+    {
+        ThisType* This = static_cast<ThisType*>(this);
+        ICDelegate<ArgTypesList ...> 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<ICDPrivate::ICDSharedDataBase>(*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 (file)
index 0000000..db86b1f
--- /dev/null
@@ -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 <dpl/event/abstract_event_dispatcher.h>
+#include <dpl/event/abstract_event_call.h>
+#include <dpl/waitable_event.h>
+#include <dpl/exception.h>
+#include <dpl/singleton.h>
+#include <dpl/mutex.h>
+#include <dpl/framework_efl.h>
+#include <list>
+
+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<WrappedEventCall> 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 (file)
index 0000000..b149eee
--- /dev/null
@@ -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 <dpl/read_write_mutex.h>
+#include <dpl/noncopyable.h>
+
+namespace DPL {
+namespace Event {
+class Model :
+    public Noncopyable
+{
+  protected:
+    mutable DPL::ReadWriteMutex m_mutex;
+
+    template<typename Type, typename StorageMethod>
+    friend class PropertyBase;
+
+    template<typename Type, typename AccessType, typename StorageMethod>
+    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 (file)
index 0000000..2ed7e0e
--- /dev/null
@@ -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<ObjectType*>(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<ObjectType*>(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 (file)
index 0000000..ce2e5c7
--- /dev/null
@@ -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 <functional>
+
+#include <dpl/event/model.h>
+#include <dpl/event/event_support.h>
+#include <dpl/assert.h>
+#include <dpl/noncopyable.h>
+#include <dpl/read_write_mutex.h>
+#include <dpl/once.h>
+
+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, property access rights, property storage mode>
+ *
+ * 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<int> Number;
+ *
+ * A property with string:
+ * @code DPL::Property<std::string> Name;
+ *
+ * A read-only float property:
+ * @code DPL::Property<float, DPL::PropertyReadOnly> Gravity;
+ *
+ * A read-write string property:
+ * @code DPL::Property<std::string, DPL::PropertyReadWrite> Caption;
+ *
+ * A read-write string property which is stored internally:
+ * @code DPL::Property<std::string,
+ *                     DPL::PropertyReadWrite,
+ *                     DPL::PropertyStorageCached> Name;
+ *
+ * A read-write string property which is stored externally:
+ * @code DPL::Property<std::string,
+ *                     DPL::PropertyReadWrite,
+ *                     DPL::PropertyStorageDynamic> RemoteName;
+ *
+ * A read-write string property which is stored externally, but also cached:
+ * @code DPL::Property<std::string,
+ *                     DPL::PropertyReadOnly,
+ *                     DPL::PropertyStorageDynamicCached> 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<int> Number1;
+ *     DPL::Property<int> Number2;
+ *     DPL::Property<int, DPL::PropertyReadOnly> 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<int> 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<typename Type>
+struct PropertyEvent
+{
+    PropertyEvent(const Type &v, Model *s) :
+        value(v),
+        sender(s)
+    {}
+
+    Type value;
+    Model *sender;
+};
+
+template<typename ReadDelegateType, typename WriteDelegateType>
+class PropertyStorageMethodDynamicBase
+{
+  protected:
+    ReadDelegateType m_readValue;
+    WriteDelegateType m_writeValue;
+
+    PropertyStorageMethodDynamicBase(ReadDelegateType readValue,
+                                     WriteDelegateType writeValue) :
+        m_readValue(readValue),
+        m_writeValue(writeValue)
+    {}
+};
+
+template<typename Type>
+class PropertyStorageMethodCachedBase
+{
+  protected:
+    mutable Type m_value;
+
+    PropertyStorageMethodCachedBase()
+    {}
+};
+
+class PropertyStorageMethodBase
+{
+  protected:
+    explicit PropertyStorageMethodBase(Model *model) :
+        m_model(model)
+    {}
+
+    Model *m_model;
+};
+
+template<typename Type,
+         typename StorageMethod,
+         typename ReadDelegateType,
+         typename WriteDelegateType>
+class PropertyStorageMethod;
+
+template<typename Type,
+         typename ReadDelegateType,
+         typename WriteDelegateType>
+class PropertyStorageMethod<Type,
+                            PropertyStorageCached,
+                            ReadDelegateType,
+                            WriteDelegateType>:
+    protected PropertyStorageMethodBase,
+    protected PropertyStorageMethodCachedBase<Type>
+{
+  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<typename Type, typename ReadDelegateType, typename WriteDelegateType>
+class PropertyStorageMethod<Type,
+                            PropertyStorageDynamic,
+                            ReadDelegateType,
+                            WriteDelegateType>:
+    protected PropertyStorageMethodBase,
+    protected PropertyStorageMethodDynamicBase<ReadDelegateType,
+                                               WriteDelegateType>
+{
+  public:
+    PropertyStorageMethod(Model *model,
+                          ReadDelegateType readValue,
+                          WriteDelegateType writeValue) :
+        PropertyStorageMethodBase(model),
+        PropertyStorageMethodDynamicBase<ReadDelegateType, WriteDelegateType>(
+            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<typename Type, typename ReadDelegateType, typename WriteDelegateType>
+class PropertyStorageMethod<Type,
+                            PropertyStorageDynamicCached,
+                            ReadDelegateType,
+                            WriteDelegateType>:
+    protected PropertyStorageMethodBase,
+    protected PropertyStorageMethodDynamicBase<ReadDelegateType,
+                                               WriteDelegateType>,
+    protected PropertyStorageMethodCachedBase<Type>
+{
+  private:
+    typedef PropertyStorageMethod<Type,
+                                  PropertyStorageDynamicCached,
+                                  ReadDelegateType,
+                                  WriteDelegateType> 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<ReadDelegateType, WriteDelegateType>(
+            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<typename Type, typename StorageMethod>
+class PropertyBase :
+    protected EventSupport<PropertyEvent<Type> >
+{
+  public:
+    typedef typename EventSupport<PropertyEvent<Type> >::EventListenerType
+    EventListenerType;
+
+    typedef typename EventSupport<PropertyEvent<Type> >::DelegateType
+    DelegateType;
+
+    typedef std::function<Type(Model *)>
+    ReadDelegateType;
+
+    typedef std::function<void (const Type &, Model *)>
+    WriteDelegateType;
+
+  protected:
+    PropertyStorageMethod<Type,
+                          StorageMethod,
+                          ReadDelegateType,
+                          WriteDelegateType> 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<PropertyEvent<Type> >::AddListener(delegate);
+    }
+
+    void RemoveListener(DelegateType delegate)
+    {
+        EventSupport<PropertyEvent<Type> >::RemoveListener(delegate);
+    }
+};
+
+template<typename Type,
+         typename AccessType = PropertyReadWrite,
+         typename StorageMethod = PropertyStorageCached>
+class Property;
+
+template<typename Type, typename StorageMethod>
+class Property<Type, PropertyReadOnly, StorageMethod>:
+    public PropertyBase<Type, StorageMethod>
+{
+  public:
+    typedef typename PropertyBase<Type, StorageMethod>::EventListenerType
+    EventListenerType;
+
+    typedef typename PropertyBase<Type, StorageMethod>::DelegateType
+    DelegateType;
+
+    typedef typename PropertyBase<Type, StorageMethod>::ReadDelegateType
+    ReadDelegateType;
+
+    typedef typename PropertyBase<Type, StorageMethod>::WriteDelegateType
+    WriteDelegateType;
+
+  public:
+    explicit Property(Model *model,
+                      ReadDelegateType readValue = NULL) :
+        PropertyBase<Type, StorageMethod>(model, readValue, NULL)
+    {}
+
+    Property(Model *model,
+             const Type &value,
+             ReadDelegateType readValue = NULL) :
+        PropertyBase<Type, StorageMethod>(model, readValue, NULL)
+    {
+        this->m_storage.Set(value);
+    }
+};
+
+template<typename Type, typename StorageMethod>
+class Property<Type, PropertyReadWrite, StorageMethod>:
+    public PropertyBase<Type, StorageMethod>
+{
+  public:
+    typedef typename PropertyBase<Type, StorageMethod>::EventListenerType
+    EventListenerType;
+
+    typedef typename PropertyBase<Type, StorageMethod>::DelegateType
+    DelegateType;
+
+    typedef typename PropertyBase<Type, StorageMethod>::ReadDelegateType
+    ReadDelegateType;
+
+    typedef typename PropertyBase<Type, StorageMethod>::WriteDelegateType
+    WriteDelegateType;
+
+  public:
+    explicit Property(Model *model,
+                      ReadDelegateType readValue = NULL,
+                      WriteDelegateType writeValue = NULL) :
+        PropertyBase<Type, StorageMethod>(model, readValue, writeValue)
+    {}
+
+    Property(Model *model,
+             const Type &value,
+             ReadDelegateType readValue = NULL,
+             WriteDelegateType writeValue = NULL) :
+        PropertyBase<Type, StorageMethod>(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<Type>(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 (file)
index 0000000..f3846a6
--- /dev/null
@@ -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 <dpl/event/abstract_event_dispatcher.h>
+#include <dpl/event/abstract_event_call.h>
+#include <dpl/thread.h>
+
+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 (file)
index 0000000..748b6da
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/event/abstract_event_call.h>
+
+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 (file)
index 0000000..7c385a4
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/event/abstract_event_dispatcher.h>
+
+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 (file)
index 0000000..337a39f
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/event/controller.h>
+
+//
+// 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 (file)
index 0000000..5d0d382
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/event/event_listener.h>
+
+//
+// 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 (file)
index 0000000..d2e643c
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/event/event_support.h>
+
+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 (file)
index 0000000..d0d6886
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/event/generic_event_call.h>
+
+//
+// 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 (file)
index 0000000..07e3885
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/event/inter_context_delegate.h>
+
+//
+// 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 (file)
index 0000000..c860398
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/event/main_event_dispatcher.h>
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/singleton_impl.h>
+
+namespace DPL {
+IMPLEMENT_SINGLETON(Event::MainEventDispatcher)
+
+namespace Event {
+typedef Singleton<Event::MainEventDispatcher> 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<MainEventDispatcher *>(data);
+    AbstractEventCall *abstractEventCall =
+        static_cast<AbstractEventCall *>(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<MainEventDispatcher *>(data);
+    AbstractEventCall *abstractEventCall =
+        static_cast<AbstractEventCall *>(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<TimedEventStruct *>(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<void *>(This),
+                      static_cast<void *>(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<MainEventDispatcher *>(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 (file)
index 0000000..58e9a1b
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/event/model.h>
+
+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 (file)
index 0000000..7da99a2
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/event/thread_event_dispatcher.h>
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+
+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<AbstractEventCall *>(event);
+    ThreadEventDispatcher *This =
+        static_cast<ThreadEventDispatcher *>(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<AbstractEventCall *>(event);
+    ThreadEventDispatcher *This =
+        static_cast<ThreadEventDispatcher *>(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 (file)
index 0000000..9b1b175
--- /dev/null
@@ -0,0 +1 @@
+ADD_SUBDIRECTORY(dao)
diff --git a/modules/i18n/dao/CMakeLists.txt b/modules/i18n/dao/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ae2d630
--- /dev/null
@@ -0,0 +1,65 @@
+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/)
+
+###############################################################################
+
+INCLUDE(FindPkgConfig)
+
+PKG_CHECK_MODULES(I18N_DAO_DEPS
+    dlog
+    REQUIRED)
+
+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 (file)
index 0000000..7e8ef9d
--- /dev/null
@@ -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 <dpl/string.h>
+
+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 (file)
index 0000000..3492f63
--- /dev/null
@@ -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 <dpl/thread.h>
+#include <dpl/mutex.h>
+#include <dpl/db/thread_database_support.h>
+
+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<InternalType> *tlsCommand##Ptr = NULL;     \
+    {                                                                          \
+        DPL::Mutex::ScopedLock lock(                                           \
+            &I18n::DB::Interface::g_dbQueriesMutex);                           \
+        if (!tlsCommand##Ptr) {                                                \
+            static DPL::ThreadLocalVariable<InternalType> tmp;                 \
+            tlsCommand##Ptr = &tmp;                                            \
+        }                                                                      \
+    }                                                                          \
+    DPL::ThreadLocalVariable<InternalType> &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 (executable)
index 0000000..22c2530
--- /dev/null
@@ -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 (file)
index 0000000..ee94c0a
--- /dev/null
@@ -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 (file)
index 0000000..d8f326d
--- /dev/null
@@ -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 <dpl/db/orm_macros.h>
+
+#include "i18n_db_definitions"
diff --git a/modules/i18n/dao/orm/iana_db b/modules/i18n/dao/orm/iana_db
new file mode 100644 (file)
index 0000000..ffd41ea
--- /dev/null
@@ -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 (file)
index 0000000..53cfea3
--- /dev/null
@@ -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 <dpl/db/orm_generator.h>
+#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 (file)
index 0000000..7e20d8d
--- /dev/null
@@ -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 (file)
index 0000000..19822ff
--- /dev/null
@@ -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 <wrt-commons/i18n-dao-ro/i18n_dao_read_only.h>
+#include <wrt-commons/i18n-dao-ro/i18n_database.h>
+
+#include <orm_generator_i18n.h>
+
+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<iana_records::SUBTAG>(tag),
+                    Equals<iana_records::TYPE>(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 (file)
index 0000000..e1a1fc5
--- /dev/null
@@ -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 <wrt-commons/i18n-dao-ro/i18n_database.h>
+
+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 (file)
index 0000000..80f77c4
--- /dev/null
@@ -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 (file)
index 0000000..529101f
--- /dev/null
@@ -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 <dpl/optional.h>
+#include <dpl/string.h>
+#include <dpl/singleton.h>
+#include <list>
+
+typedef std::list<DPL::String> 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<LanguageTagsProvider>;
+
+    LanguageTags m_languageTagsList;
+
+    LanguageTagsProvider();
+    virtual ~LanguageTagsProvider();
+
+    void loadSystemTags();
+    void createTagsFromLocales(const char* language);
+};
+
+typedef DPL::Singleton<LanguageTagsProvider> 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 (file)
index 0000000..66a232d
--- /dev/null
@@ -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 <list>
+
+#include <dpl/log/log.h>
+#include <dpl/optional.h>
+#include <dpl/read_write_mutex.h>
+#include <dpl/string.h>
+
+/**
+ * WidgetIcon
+ * Structure to hold information about widget icon.
+ */
+
+struct WidgetIcon
+{
+    WidgetIcon() :
+        width(DPL::Optional<int>::Null),
+        height(DPL::Optional<int>::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<int> width;       /// the width of the icon in pixels
+    DPL::Optional<int> 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<WidgetIcon> OptionalWidgetIcon;
+typedef DPL::Optional<WidgetStartFileInfo> 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 (executable)
index 0000000..7a437d8
--- /dev/null
@@ -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 <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/optional.h>
+#include <dpl/string.h>
+#include <list>
+
+#include <dpl/localization/localization_utils.h>
+
+// WrtDB::DbWidgetHandle
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+namespace W3CFileLocalization {
+typedef std::list<WidgetIcon> WidgetIconList;
+
+DPL::Optional<DPL::String> getFilePathInWidgetPackageFromUrl(
+    const WrtDB::TizenAppId &tzAppId,
+    const DPL::String &url);
+DPL::Optional<DPL::String> getFilePathInWidgetPackageFromUrl(
+    WrtDB::WidgetDAOReadOnlyPtr dao,
+    const DPL::String &url);
+std::string getFilePathInWidgetPackageFromUrl(const std::string &tzAppId, const std::string &url);
+
+DPL::Optional<DPL::String> getFilePathInWidgetPackage(
+    const WrtDB::TizenAppId &tzAppId,
+    const DPL::String& file);
+DPL::Optional<DPL::String> 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 (file)
index 0000000..848cc34
--- /dev/null
@@ -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 <algorithm>
+#include <cassert>
+#include <iostream>
+#include <locale>
+#include <cstddef>
+#include <string>
+
+#include <dpl/log/log.h>
+#include <dpl/singleton_impl.h>
+#include <vconf.h>
+
+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 (file)
index 0000000..438c62b
--- /dev/null
@@ -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 <stddef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <dpl/localization/w3c_file_localization.h>
+
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/localization/localization_utils.h>
+
+#include <dpl/log/log.h>
+#include <dpl/string.h>
+#include <dpl/optional.h>
+#include <dpl/foreach.h>
+
+#include <LanguageTagsProvider.h>
+
+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<std::string> 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<std::string>::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<std::string>::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<std::string>(path);
+            }
+        }
+    }
+
+    return DPL::Optional<std::string>::Null;
+}
+
+DPL::Optional<DPL::String> GetFilePathInWidgetPackageInternal(
+    const DPL::String& basePath,
+    const DPL::String& filePath)
+{
+    DPL::Optional<std::string> path =
+        GetFilePathInWidgetPackageInternal(DPL::ToUTF8String(basePath),
+                                           DPL::ToUTF8String(filePath));
+    DPL::Optional<DPL::String> dplPath;
+    if (!!path) {
+        dplPath = DPL::FromUTF8String(*path);
+    }
+    return dplPath;
+}
+}
+
+namespace W3CFileLocalization {
+static bool isExistFileCached(const std::string& path)
+{
+    static std::map<std::string, bool> 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<DPL::String> getFilePathInWidgetPackageFromUrl(
+    const WrtDB::TizenAppId &tzAppId,
+    const DPL::String &url)
+{
+    return getFilePathInWidgetPackageFromUrl(
+               WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)),
+               url);
+}
+
+DPL::Optional<DPL::String> 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<DPL::String>::Null;
+        }
+        req.erase(0, id.length());
+    } else {
+        LogDebug("Unknown path format, ignoring");
+        return DPL::Optional<DPL::String>::Null;
+    }
+
+    auto widgetPath = dao->getPath();
+
+    LogDebug("Required path: " << req);
+    DPL::Optional<DPL::String> found =
+        GetFilePathInWidgetPackageInternal(widgetPath, req);
+
+    if (!found) {
+        LogError("Path not found within current locale in current widget");
+        return DPL::Optional<DPL::String>::Null;
+    }
+
+    found = widgetPath + *found + suffix;
+
+    return found;
+}
+
+DPL::Optional<DPL::String> getFilePathInWidgetPackage(
+    const WrtDB::TizenAppId &tzAppId,
+    const DPL::String& file)
+{
+    return getFilePathInWidgetPackage(
+               WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)),
+               file);
+}
+
+DPL::Optional<DPL::String> 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 (file)
index 0000000..30ad033
--- /dev/null
@@ -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 (file)
index 0000000..62fa050
--- /dev/null
@@ -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 (file)
index 0000000..1dd4c2d
--- /dev/null
@@ -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 <dpl/log/abstract_log_provider.h>
+#include <dpl/scoped_free.h>
+#include <string>
+
+namespace DPL {
+namespace Log {
+class DLOGLogProvider :
+    public AbstractLogProvider
+{
+  private:
+    DPL::ScopedFree<char> 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 (file)
index 0000000..d4d95ed
--- /dev/null
@@ -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 <dpl/singleton.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/abstract_log_provider.h>
+#include <dpl/log/dlog_log_provider.h>
+#include <dpl/log/old_style_log_provider.h>
+#include <sstream>
+#include <list>
+
+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<AbstractLogProvider *> 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 <typename T>
+    NullStream& operator<<(const T&)
+    {
+        return *this;
+    }
+};
+
+/**
+ * Log system singleton
+ */
+typedef Singleton<LogSystem> 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 (file)
index 0000000..70e308a
--- /dev/null
@@ -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 <dpl/log/abstract_log_provider.h>
+#include <string>
+
+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 (file)
index 0000000..6402c4f
--- /dev/null
@@ -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 <dlog.h>
+
+#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 (file)
index 0000000..a03f8a0
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/log/abstract_log_provider.h>
+#include <cstring>
+
+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 (file)
index 0000000..1a203db
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/log/dlog_log_provider.h>
+#include <cstring>
+#include <sstream>
+#include <dlog.h>
+
+#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 (file)
index 0000000..7c0ebc2
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/log/log.h>
+#include <dpl/singleton_impl.h>
+
+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 (file)
index 0000000..b8060dd
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/log/old_style_log_provider.h>
+#include <dpl/colors.h>
+#include <cstdio>
+#include <cstring>
+#include <sstream>
+#include <sys/time.h>
+#include <unistd.h>
+
+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<int>(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<unsigned long>(pthread_self()) << "/" <<
+    static_cast<int>(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 (file)
index 0000000..9f3d810
--- /dev/null
@@ -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 (file)
index 0000000..7857c60
--- /dev/null
@@ -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 <dpl/rpc/rpc_function.h>
+#include <dpl/exception.h>
+#include <dpl/generic_event.h>
+#include <dpl/event/event_support.h>
+#include <memory>
+#include <string>
+
+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<AbstractRPCConnectionEvents::AsyncCallEvent>,
+    public DPL::Event::EventSupport<AbstractRPCConnectionEvents::
+                                        ConnectionClosedEvent>,
+    public DPL::Event::EventSupport<AbstractRPCConnectionEvents::
+                                        ConnectionBrokenEvent>
+{
+  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 (file)
index 0000000..c9e3b1f
--- /dev/null
@@ -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 <dpl/rpc/abstract_rpc_connection.h>
+#include <dpl/event/event_support.h>
+#include <dpl/generic_event.h>
+
+namespace DPL {
+namespace RPC {
+namespace AbstractRPCConnectorEvents {
+/**
+ * RPC connection established
+ */
+DECLARE_GENERIC_EVENT_2(ConnectionEstablishedEvent,
+                        AbstractRPCConnectionID,
+                        AbstractRPCConnection *)
+} // namespace AbstractRPCClientEvents
+
+class AbstractRPCConnector :
+    public DPL::Event::EventSupport<AbstractRPCConnectorEvents::
+                                        ConnectionEstablishedEvent>
+{
+  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 (file)
index 0000000..d9614c6
--- /dev/null
@@ -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 <dpl/rpc/abstract_rpc_connection.h>
+#include <dpl/abstract_waitable_input_output.h>
+#include <dpl/socket/waitable_input_output_execution_context_support.h>
+#include <memory>
+
+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<AbstractWaitableInputOutput> 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 (file)
index 0000000..9629e61
--- /dev/null
@@ -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 <dpl/rpc/abstract_rpc_connector.h>
+#include <dpl/socket/abstract_socket.h>
+#include <set>
+
+namespace DPL {
+namespace RPC {
+template<typename SocketType>
+class GenericSocketRPCClient :
+    public AbstractRPCConnector,
+    private DPL::Event::EventListener<DPL::Socket::AbstractSocketEvents::
+                                          ConnectedEvent>
+{
+  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<SocketType *> InternalConnectionSet;
+    InternalConnectionSet m_internalConnectionSet;
+
+    virtual void OnEventReceived(
+        const DPL::Socket::AbstractSocketEvents::ConnectedEvent &event)
+    {
+        // Retrieve socket sender
+        SocketType *socket = static_cast<SocketType *>(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<DPL::Socket::AbstractSocketEvents::ConnectedEvent>
+            ::RemoveListener(this);
+        m_internalConnectionSet.erase(iterator);
+
+        // Retrieve ID once again
+        AbstractRPCConnectionID connectionID =
+            static_cast<AbstractRPCConnectionID>(socket);
+
+        // Inform listeners
+        DPL::Event::EventSupport<AbstractRPCConnectorEvents::
+                                     ConnectionEstablishedEvent>::
+            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<DPL::Socket::AbstractSocketEvents::ConnectedEvent>
+            ::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<DPL::Socket::AbstractSocketEvents::
+                                     ConnectedEvent>::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<AbstractRPCConnectionID>(socket);
+    }
+
+    void Close(AbstractRPCConnectionID connectionID)
+    {
+        LogPedantic("Closing client interface...");
+
+        // Get socket from ID
+        SocketType *socket = static_cast<SocketType *>(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<DPL::Socket::AbstractSocketEvents::ConnectedEvent>
+            ::RemoveListener(this);
+        delete socket;
+
+        m_internalConnectionSet.erase(iterator);
+
+        // Done
+        LogPedantic("Closed");
+    }
+
+    void CloseAll()
+    {
+        while (!m_internalConnectionSet.empty()) {
+            Close(static_cast<AbstractRPCConnectionID>(*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 (file)
index 0000000..6c2d0ce
--- /dev/null
@@ -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 <dpl/rpc/generic_rpc_connection.h>
+
+namespace DPL {
+namespace RPC {
+template<class SocketType>
+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 (file)
index 0000000..a4cae00
--- /dev/null
@@ -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 <dpl/rpc/abstract_rpc_connector.h>
+#include <dpl/socket/abstract_socket.h>
+#include <set>
+
+namespace DPL {
+namespace RPC {
+template<typename SocketType>
+class GenericSocketRPCServer :
+    public AbstractRPCConnector,
+    private DPL::Event::EventListener<DPL::Socket::AbstractSocketEvents::
+                                          AcceptEvent>
+{
+  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<SocketType *> InternalInterfaceSet;
+    InternalInterfaceSet m_internalInterfacesSet;
+
+    virtual void OnEventReceived(
+        const DPL::Socket::AbstractSocketEvents::AcceptEvent &event)
+    {
+        // Retrieve socket sender
+        SocketType *server = static_cast<SocketType *>(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<SocketType *>(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<AbstractRPCConnectionID>(server);
+
+        // Inform listeners
+        DPL::Event::EventSupport<AbstractRPCConnectorEvents::
+                                     ConnectionEstablishedEvent>::
+            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<DPL::Socket::AbstractSocketEvents::AcceptEvent>::
+            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<DPL::Socket::AbstractSocketEvents::AcceptEvent>
+                ::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<AbstractRPCConnectionID>(socket);
+    }
+
+    void Close(AbstractRPCConnectionID connectionID)
+    {
+        LogPedantic("Closing server interface...");
+
+        // Get socket from ID
+        SocketType *socket = static_cast<SocketType *>(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<DPL::Socket::AbstractSocketEvents::AcceptEvent>::
+            RemoveListener(this);
+        delete socket;
+
+        m_internalInterfacesSet.erase(iterator);
+
+        // Done
+        LogPedantic("Closed");
+    }
+
+    void CloseAll()
+    {
+        while (!m_internalInterfacesSet.empty()) {
+            Close(static_cast<AbstractRPCConnectionID>(*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 (file)
index 0000000..a01235f
--- /dev/null
@@ -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 <dpl/exception.h>
+#include <dpl/binary_queue.h>
+#include <dpl/scoped_array.h>
+#include <dpl/string.h>
+#include <dpl/serialization.h>
+#include <string>
+
+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<typename Type>
+    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<typename Type>
+    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<char> 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 (file)
index 0000000..aba62ec
--- /dev/null
@@ -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 <dpl/rpc/generic_socket_rpc_client.h>
+#include <dpl/socket/unix_socket.h>
+#include <string>
+
+namespace DPL {
+namespace RPC {
+class UnixSocketRPCClient :
+    public GenericSocketRPCClient<DPL::Socket::UnixSocket>
+{
+  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 (file)
index 0000000..9b00141
--- /dev/null
@@ -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 <dpl/rpc/generic_socket_rpc_connection.h>
+#include <dpl/socket/unix_socket.h>
+
+namespace DPL {
+namespace RPC {
+class UnixSocketRPCConnection :
+    public GenericSocketRPCConnection<DPL::Socket::UnixSocket>
+{
+  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 (file)
index 0000000..de2b605
--- /dev/null
@@ -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 <dpl/rpc/generic_socket_rpc_server.h>
+#include <dpl/socket/unix_socket.h>
+#include <string>
+
+namespace DPL {
+namespace RPC {
+class UnixSocketRPCServer :
+    public GenericSocketRPCServer<DPL::Socket::UnixSocket>
+{
+  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 (file)
index 0000000..e5455e2
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/rpc/abstract_rpc_connection.h>
+
+//
+// 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 (file)
index 0000000..2bd879e
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/rpc/abstract_rpc_connector.h>
+
+//
+// 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 (file)
index 0000000..6b16f28
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/rpc/generic_rpc_connection.h>
+#include <dpl/scoped_array.h>
+#include <dpl/log/log.h>
+#include <dpl/aligned.h>
+#include <stdexcept>
+
+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<unsigned short>(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<AbstractRPCConnectionEvents::
+                                                 AsyncCallEvent>::
+                        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<AbstractRPCConnectionEvents::ConnectionClosedEvent>
+        ::
+        EmitEvent(AbstractRPCConnectionEvents::ConnectionClosedEvent(
+                      EventSender(this)), DPL::Event::EmitMode::Queued);
+}
+
+void GenericRPCConnection::OnInputStreamBroken()
+{
+    // Emit broken event
+    DPL::Event::EventSupport<AbstractRPCConnectionEvents::ConnectionBrokenEvent>
+        ::
+        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 (file)
index 0000000..51c1b97
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/rpc/generic_socket_rpc_client.h>
+
+//
+// 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 (file)
index 0000000..2d84a4a
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/rpc/generic_socket_rpc_connection.h>
+
+//
+// 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 (file)
index 0000000..a0590f4
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/rpc/generic_socket_rpc_server.h>
+
+//
+// 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 (file)
index 0000000..8b105f2
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/rpc/unix_socket_rpc_client.h>
+#include <dpl/rpc/unix_socket_rpc_connection.h>
+
+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<DPL::Socket::UnixSocket>::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 (file)
index 0000000..b21098d
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/rpc/unix_socket_rpc_connection.h>
+
+namespace DPL {
+namespace RPC {
+UnixSocketRPCConnection::UnixSocketRPCConnection(
+    DPL::Socket::UnixSocket *socket) :
+    GenericSocketRPCConnection<DPL::Socket::UnixSocket>(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 (file)
index 0000000..e9dd9ab
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/rpc/unix_socket_rpc_server.h>
+#include <dpl/rpc/unix_socket_rpc_connection.h>
+
+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<DPL::Socket::UnixSocket>::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 (file)
index 0000000..3375925
--- /dev/null
@@ -0,0 +1,56 @@
+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
+    dlog
+    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 (file)
index 0000000..7551189
--- /dev/null
@@ -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 <wrt-commons/security-origin-dao/security_origin_dao.h>
+#include <wrt-commons/security-origin-dao/security_origin_dao_types.h>
+#include <orm_generator_security_origin.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <dpl/wrt-dao-ro/widget_config.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+#include <sys/stat.h>
+#include <fstream>
+#include <unistd.h>
+
+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<SecurityOriginInfo::Row> 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<Feature>(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<SecurityOriginInfo::feature> eFeature(data.feature);
+        Equals<SecurityOriginInfo::scheme> eScheme(data.origin.scheme);
+        Equals<SecurityOriginInfo::host> eHost(data.origin.host);
+        Equals<SecurityOriginInfo::port> 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<Result>(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<SecurityOriginInfo::feature> eFeature(data.feature);
+        Equals<SecurityOriginInfo::scheme> eScheme(data.origin.scheme);
+        Equals<SecurityOriginInfo::host> eHost(data.origin.host);
+        Equals<SecurityOriginInfo::port> 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<SecurityOriginInfo::feature> eFeature(data.feature);
+        Equals<SecurityOriginInfo::scheme> eScheme(data.origin.scheme);
+        Equals<SecurityOriginInfo::host> eHost(data.origin.host);
+        Equals<SecurityOriginInfo::port> 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<SecurityOriginInfo::result>(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<SecurityOriginInfo::feature> eFeature(data.feature);
+        Equals<SecurityOriginInfo::scheme> eScheme(data.origin.scheme);
+        Equals<SecurityOriginInfo::host> eHost(data.origin.host);
+        Equals<SecurityOriginInfo::port> 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 (executable)
index 0000000..8d2a9f8
--- /dev/null
@@ -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 <wrt-commons/security-origin-dao/security_origin_dao_types.h>
+#include <dpl/log/log.h>
+
+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 (file)
index 0000000..d922764
--- /dev/null
@@ -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 <dpl/db/thread_database_support.h>
+#include <wrt-commons/security-origin-dao/security_origin_dao_types.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+#include <dpl/wrt-dao-ro/widget_dao_types.h>
+
+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<SecurityOriginDAO> 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 (executable)
index 0000000..4753925
--- /dev/null
@@ -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 <list>
+#include <memory>
+#include <map>
+#include <dpl/string.h>
+#include <dpl/wrt-dao-ro/widget_dao_types.h>
+
+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<SecurityOriginData> SecurityOriginDataPtr;
+typedef std::list<SecurityOriginDataPtr> 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 (file)
index 0000000..84888de
--- /dev/null
@@ -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 <dpl/db/orm_generator.h>
+#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 (file)
index 0000000..2d9c4f9
--- /dev/null
@@ -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 (file)
index 0000000..dc74f98
--- /dev/null
@@ -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 (file)
index 0000000..3bdbe6d
--- /dev/null
@@ -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 <dpl/db/orm_macros.h>
+
+#include "security_origin_db_definitions"
diff --git a/modules/socket/config.cmake b/modules/socket/config.cmake
new file mode 100644 (file)
index 0000000..6e097a4
--- /dev/null
@@ -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 (file)
index 0000000..0c06f99
--- /dev/null
@@ -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 <dpl/abstract_waitable_input_output.h>
+#include <dpl/event/event_support.h>
+#include <dpl/generic_event.h>
+#include <dpl/exception.h>
+#include <dpl/address.h>
+
+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<AbstractSocketEvents::ConnectedEvent>,
+    public DPL::Event::EventSupport<AbstractSocketEvents::AcceptEvent>,
+    public DPL::Event::EventSupport<AbstractSocketEvents::ReadEvent>,
+    public DPL::Event::EventSupport<AbstractSocketEvents::WriteEvent>
+{
+  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 (file)
index 0000000..3ed9b86
--- /dev/null
@@ -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 <dpl/socket/abstract_socket.h>
+#include <dpl/waitable_handle_watch_support.h>
+#include <dpl/binary_queue.h>
+#include <dpl/thread.h>
+#include <dpl/main.h>
+#include <dpl/log/log.h>
+#include <dpl/scoped_free.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dpl/assert.h>
+
+namespace DPL {
+namespace Socket {
+//
+// Generic abstract socket implementation
+// Execution context is inherited
+//
+template<typename SocketType>
+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<sockaddr *, socklen_t> 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<AbstractSocketEvents::AcceptEvent>::
+                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<AbstractSocketEvents::ConnectedEvent>::
+                EmitEvent(AbstractSocketEvents::ConnectedEvent(
+                              EventSender(this)), DPL::Event::EmitMode::Queued);
+
+            // Done
+            break;
+
+        case InternalState_Connected:
+            if (mode == WaitMode::Read) {
+                // Emit ReadEvent
+                DPL::Event::EventSupport<AbstractSocketEvents::ReadEvent>::
+                    EmitEvent(AbstractSocketEvents::ReadEvent(
+                                  EventSender(
+                                      this)), DPL::Event::EmitMode::Queued);
+            } else if (mode == WaitMode::Write) {
+                // Emit WriteEvent
+                DPL::Event::EventSupport<AbstractSocketEvents::WriteEvent>::
+                    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<sockaddr *, socklen_t> 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<AbstractSocketEvents::ConnectedEvent>::
+                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<sockaddr *,
+                  socklen_t> 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<sockaddr> address(static_cast<sockaddr *>(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<sockaddr> address(static_cast<sockaddr *>(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<void> 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<size_t>(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 (file)
index 0000000..37614ce
--- /dev/null
@@ -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 <dpl/socket/generic_socket.h>
+#include <dpl/exception.h>
+
+namespace DPL {
+namespace Socket {
+class UnixSocket :
+    public GenericSocket<UnixSocket>
+{
+  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<sockaddr *, socklen_t> 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 (file)
index 0000000..f02df51
--- /dev/null
@@ -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 <dpl/abstract_waitable_input_output.h>
+#include <dpl/waitable_handle_watch_support.h>
+#include <dpl/binary_queue.h>
+
+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 (file)
index 0000000..aff2d74
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/socket/generic_socket.h>
+
+//
+// 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 (file)
index 0000000..36bff51
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/socket/unix_socket.h>
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+#include <new>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+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<sockaddr *, socklen_t> UnixSocket::TranslateAddressGenericToSpecific(
+    const Address &address) const
+{
+    // Allocate new socket address structure
+    sockaddr_un *sockAddress =
+        static_cast<sockaddr_un *>(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<sockaddr *>(sockAddress),
+                          sockAddressLength);
+}
+
+Address UnixSocket::TranslateAddressSpecificToGeneric(sockaddr *address,
+                                                      socklen_t) const
+{
+    // FIXME: Constrain check ?
+    sockaddr_un *unixAddress = reinterpret_cast<sockaddr_un *>(address);
+    return Address(unixAddress->sun_path);
+}
+
+socklen_t UnixSocket::GetSpecificAddressSize() const
+{
+    return static_cast<socklen_t>(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<UnixSocket>::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 (file)
index 0000000..35635b5
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/socket/waitable_input_output_execution_context_support.h>
+#include <dpl/scoped_array.h>
+#include <dpl/socket/abstract_socket.h> // FIXME: Remove !!!
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+
+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 (file)
index 0000000..e2865f6
--- /dev/null
@@ -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 (executable)
index 0000000..0cf4e37
--- /dev/null
@@ -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 <stddef.h>
+
+/**
+ * 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 (file)
index 0000000..8310c3c
--- /dev/null
@@ -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 (file)
index 0000000..dcb2243
--- /dev/null
@@ -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 <dpl/exception.h>
+
+#include <memory>
+
+namespace DPL {
+
+/**
+ * Abstract class of parser that produces some higher level abstraction
+ * basing on incoming tokens
+ */
+template<class Result, class Token> 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> && 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 (file)
index 0000000..6b23dd6
--- /dev/null
@@ -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 <memory>
+
+#include <dpl/optional.h>
+#include <dpl/test/abstract_input_tokenizer.h>
+#include <dpl/test/abstract_input_parser.h>
+#include <dpl/abstract_input.h>
+
+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 ResultT, class TokenT> class AbstractInputReader
+{
+public:
+    typedef ResultT TokenType;
+    typedef TokenT ResultType;
+    typedef AbstractInputParser<ResultT, TokenT> ParserBase;
+    typedef AbstractInputTokenizer<TokenT> TokenizerBase;
+
+    class Exception
+    {
+    public:
+        typedef typename TokenizerBase::Exception::TokenizerError TokenizerError;
+        typedef typename ParserBase::Exception::ParserError ParserError;
+    };
+
+    AbstractInputReader(std::shared_ptr<AbstractInput> ia,
+                        std::unique_ptr<ParserBase> && parser,
+                        std::unique_ptr<TokenizerBase> && 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<TokenT> 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<ParserBase> m_parser;
+    std::unique_ptr<TokenizerBase> 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 (file)
index 0000000..a376341
--- /dev/null
@@ -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 <memory>
+#include <string>
+
+#include <dpl/abstract_input.h>
+#include <dpl/optional.h>
+#include <dpl/exception.h>
+
+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 Token> 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<AbstractInput> 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<Token> GetNextToken() = 0;
+    virtual bool IsStateValid() = 0;
+
+protected:
+    std::shared_ptr<AbstractInput> 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 (file)
index 0000000..52ab7e7
--- /dev/null
@@ -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 <dpl/file_input.h>
+#include <dpl/exception.h>
+
+#include <cstdio>
+
+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 (file)
index 0000000..acb2914
--- /dev/null
@@ -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 <dpl/noncopyable.h>
+#include <dpl/availability.h>
+#include <vector>
+#include <list>
+#include <map>
+#include <string>
+#include <memory>
+
+namespace DPL {
+namespace Test {
+class TestResultsCollectorBase;
+typedef std::shared_ptr<TestResultsCollectorBase>
+TestResultsCollectorBasePtr;
+
+class TestResultsCollectorBase :
+    private DPL::Noncopyable
+{
+  public:
+    typedef TestResultsCollectorBase* (*CollectorConstructorFunc)();
+    typedef std::list<std::string> 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<std::string> GetCollectorsNames();
+
+  private:
+    typedef std::map<std::string, CollectorConstructorFunc> 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 (file)
index 0000000..cf927ef
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES 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 <dpl/singleton.h>
+#include <dpl/availability.h>
+#include <dpl/atomic.h>
+#include <dpl/test/test_results_collector.h>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <list>
+#include <set>
+#include <map>
+
+namespace DPL {
+namespace Test {
+class TestRunner
+{
+    typedef std::map<std::string, TestResultsCollectorBasePtr>
+    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<TestCaseStruct> TestCaseStructList;
+    typedef std::map<std::string, TestCaseStructList> TestCaseGroupMap;
+    TestCaseGroupMap m_testGroups;
+
+    typedef std::set<std::string> SelectedTestNameSet;
+    SelectedTestNameSet m_selectedTestNamesSet;
+    typedef std::set<std::string> 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<std::string> & files);
+    bool filterByXML(std::map<std::string, bool> & 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<std::string> 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<TestRunner> 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()
+
+#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 (file)
index 0000000..1da0f1b
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+
+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 (file)
index 0000000..279b5ef
--- /dev/null
@@ -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 <dpl/test/test_runner_child.h>
+
+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 (file)
index 0000000..635e548
--- /dev/null
@@ -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<string>
+#include<vector>
+#include<memory>
+
+#include<dpl/test/value_separated_tokens.h>
+#include<dpl/test/abstract_input_parser.h>
+
+namespace DPL {
+
+typedef std::vector<std::string> VSLine;
+typedef std::vector<VSLine> VSResult;
+typedef std::shared_ptr<VSResult> VSResultPtr;
+
+/**
+ * Value Seperated parser
+ *
+ * Requires following policy class:
+ *
+ * template<VSResultPtr>
+ * struct CSVParserPolicy
+ * {
+ *     static bool SkipLine(VSLine & );
+ *     static bool Validate(VSResultPtr& result);
+ * };
+ */
+template<class ParserPolicy>
+class VSParser : public AbstractInputParser<VSResultPtr, VSToken>
+{
+public:
+    VSParser() : m_switchLine(true), m_result(new VSResult()) {}
+
+    void ConsumeToken(std::unique_ptr<VSToken> && 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 (file)
index 0000000..c432703
--- /dev/null
@@ -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<string>
+#include<vector>
+#include<memory>
+
+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<std::string> & );                                  //should I skip whole readline?
+    static bool Validate(std::shared_ptr<std::vector<std::vector<std::string> > > & 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 (file)
index 0000000..8e78aaa
--- /dev/null
@@ -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<dpl/test/abstract_input_reader.h>
+#include<dpl/test/value_separated_tokenizer.h>
+#include<dpl/test/value_separated_parser.h>
+#include<dpl/test/value_separated_tokens.h>
+#include<dpl/test/value_separated_policies.h>
+
+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 ParserPolicy, class TokenizerPolicy>
+class VSReader : public AbstractInputReader<VSResultPtr, VSToken>
+{
+public:
+    VSReader(std::shared_ptr<AbstractInput> wia)
+        : AbstractInputReader<VSResultPtr, VSToken>(wia,
+                std::unique_ptr<ParserBase>(new VSParser<ParserPolicy>()),
+                std::unique_ptr<TokenizerBase>(new VSTokenizer<TokenizerPolicy>()))
+    {}
+};
+
+typedef VSReader<CSVParserPolicy, CSVTokenizerPolicy> 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 (file)
index 0000000..13403b5
--- /dev/null
@@ -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<dpl/test/abstract_input_tokenizer.h>
+#include<dpl/test/value_separated_tokens.h>
+#include<dpl/binary_queue.h>
+
+
+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 TokenizerPolicy>
+class VSTokenizer : public AbstractInputTokenizer<VSToken>
+{
+public:
+    VSTokenizer() {}
+
+    void Reset(std::shared_ptr<AbstractInput> ia)
+    {
+        AbstractInputTokenizer<VSToken>::Reset(ia);
+        m_queue.Clear();
+        m_finished = false;
+        m_newline = false;
+    }
+
+    std::unique_ptr<VSToken> GetNextToken()
+    {
+        std::unique_ptr<VSToken> 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<VSToken> & 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 (file)
index 0000000..3c49157
--- /dev/null
@@ -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<string>
+
+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 (file)
index 0000000..68c910f
--- /dev/null
@@ -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<dpl/test/process_pipe.h>
+#include<dpl/log/log.h>
+
+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 (file)
index 0000000..665ca7d
--- /dev/null
@@ -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 <cstddef>
+#include <dpl/test/test_results_collector.h>
+#include <dpl/colors.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/scoped_fclose.h>
+#include <dpl/exception.h>
+#include <dpl/errno_string.h>
+#include <dpl/lexical_cast.h>
+#include <dpl/availability.h>
+
+#include <string>
+#include <string.h>
+#include <cstdio>
+#include <fstream>
+#include <sstream>
+#include <cstdlib>
+
+#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<float>(m_passed)
+                      + static_cast<float>(m_ignored))
+            / static_cast<float>(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<std::string, Statistic> 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(), "<b>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=<filename> - 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(),
+                "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0"
+                "Transitional//EN\" "
+                "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\""
+                ">\n");
+        fprintf(m_fp.Get(),
+                "<html xmlns=\"http://www.w3.org/1999/xhtml\" "
+                "lang=\"en\" dir=\"ltr\">\n");
+        fprintf(m_fp.Get(), "<body style=\"background-color: black;\">\n");
+        fprintf(m_fp.Get(), "<pre>\n");
+        fprintf(m_fp.Get(), "<font color=\"white\">\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(), "</font>\n");
+        fprintf(m_fp.Get(), "</pre>\n");
+        fprintf(m_fp.Get(), "</body>\n");
+        fprintf(m_fp.Get(), "</html>\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<std::string, Statistic> 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("</testsuites>");
+        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<testsuite";
+        groupHeader << " name=\"" << EscapeSpecialCharacters(name) << "\"";
+        groupHeader << R"( tests="1")"; // include SegFault
+        groupHeader << R"( failures="1")"; // include SegFault
+        groupHeader << R"( skipped="0")";
+        groupHeader << ">";
+
+        groupHeader << "\n\t\t<testcase name=\"unknown\" status=\"FAILED\">";
+        groupHeader <<
+        "\n\t\t\t<failure type=\"FAILED\" message=\"segmentation fault\"/>";
+        groupHeader << "\n\t\t</testcase>";
+
+        groupHeader << "\n\t</testsuite>";
+
+        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=<filename> - 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("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+        m_outputBuffer.append("<testsuites ");
+        if(count >= 0)
+        {
+            m_outputBuffer.append("total=\"");
+            m_outputBuffer.append(DPL::lexical_cast<std::string>(count));
+            m_outputBuffer.append("\"");
+        }
+        m_outputBuffer.append(" >\n</testsuites>");
+        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<testcase name=\"");
+        m_resultBuffer.append(EscapeSpecialCharacters(id));
+        m_resultBuffer.append("\"");
+        switch (status) {
+        case TestResultsCollectorBase::FailStatus::NONE:
+            m_resultBuffer.append(" status=\"OK\"/>\n");
+            break;
+        case TestResultsCollectorBase::FailStatus::FAILED:
+            m_resultBuffer.append(" status=\"FAILED\">\n");
+            PrintfErrorMessage("FAILED", EscapeSpecialCharacters(reason), true);
+            m_resultBuffer.append("\t\t</testcase>\n");
+            break;
+        case TestResultsCollectorBase::FailStatus::IGNORED:
+            m_resultBuffer.append(" status=\"Ignored\">\n");
+            PrintfIgnoredMessage("Ignored", EscapeSpecialCharacters(
+                                     reason), true);
+            m_resultBuffer.append("\t\t</testcase>\n");
+            break;
+        case TestResultsCollectorBase::FailStatus::INTERNAL:
+            m_resultBuffer.append(" status=\"FAILED\">\n");
+            PrintfErrorMessage("INTERNAL", EscapeSpecialCharacters(
+                                   reason), true);
+            m_resultBuffer.append("\t\t</testcase>");
+            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(
+                "<testcase name=\"unknown\"",
+                group_pos);
+        if (std::string::npos == last_case_pos) {
+            ThrowMsg(DPL::Exception, "Could not find SegFault test case");
+        }
+        m_outputBuffer.insert(last_case_pos - 2, m_resultBuffer);
+
+        m_stats.AddTest(status);
+
+        UpdateGroupHeader(group_pos,
+                          m_stats.GetTotal() + 1, // include SegFault
+                          m_stats.GetFailed() + 1, // include SegFault
+                          m_stats.GetIgnored());
+        FlushOutput();
+    }
+
+    std::size_t GetCurrentGroupPosition() const
+    {
+        return m_outputBuffer.rfind("<testsuite ");
+    }
+
+    void UpdateGroupHeader(const std::size_t groupPosition,
+                           const unsigned int tests,
+                           const unsigned int failures,
+                           const unsigned int skipped)
+    {
+        UpdateElementAttribute(groupPosition, "tests", UIntToString(tests));
+        UpdateElementAttribute(groupPosition, "failures", UIntToString(failures));
+        UpdateElementAttribute(groupPosition, "skipped", UIntToString(skipped));
+    }
+
+    void UpdateElementAttribute(const std::size_t elementPosition,
+                                const std::string& name,
+                                const std::string& value)
+    {
+        std::string pattern = name + "=\"";
+
+        std::size_t start = m_outputBuffer.find(pattern, elementPosition);
+        if (std::string::npos == start) {
+            ThrowMsg(DPL::Exception,
+                     "Could not find attribute " << name << " beginning");
+        }
+
+        std::size_t end = m_outputBuffer.find("\"", start + pattern.length());
+        if (std::string::npos == end) {
+            ThrowMsg(DPL::Exception,
+                     "Could not find attribute " << name << " end");
+        }
+
+        m_outputBuffer.replace(start + pattern.length(),
+                               end - start - pattern.length(),
+                               value);
+    }
+
+    std::string UIntToString(const unsigned int value)
+    {
+        std::stringstream result;
+        result << value;
+        return result.str();
+    }
+
+    void GroupFinish(const std::size_t groupPosition)
+    {
+        std::size_t segFaultStart =
+            m_outputBuffer.find("<testcase name=\"unknown\"", groupPosition);
+        if (std::string::npos == segFaultStart) {
+            ThrowMsg(DPL::Exception,
+                     "Could not find SegFault test case start position");
+        }
+        segFaultStart -= 2; // to erase tabs
+
+        std::string closeTag = "</testcase>";
+        std::size_t segFaultEnd = m_outputBuffer.find(closeTag, segFaultStart);
+        if (std::string::npos == segFaultEnd) {
+            ThrowMsg(DPL::Exception,
+                     "Could not find SegFault test case end position");
+        }
+        segFaultEnd += closeTag.length() + 1; // to erase new line
+
+        m_outputBuffer.erase(segFaultStart, segFaultEnd - segFaultStart);
+
+        UpdateGroupHeader(groupPosition,
+                          m_stats.GetTotal(),
+                          m_stats.GetFailed(),
+                          m_stats.GetIgnored());
+    }
+
+    void FlushOutput()
+    {
+        int fd = fileno(m_fp.Get());
+        if (-1 == fd) {
+            int error = errno;
+            ThrowMsg(DPL::Exception, DPL::GetErrnoString(error));
+        }
+
+        if (-1 == TEMP_FAILURE_RETRY(ftruncate(fd, 0L))) {
+            int error = errno;
+            ThrowMsg(DPL::Exception, DPL::GetErrnoString(error));
+        }
+
+        if (-1 == TEMP_FAILURE_RETRY(fseek(m_fp.Get(), 0L, SEEK_SET))) {
+            int error = errno;
+            ThrowMsg(DPL::Exception, DPL::GetErrnoString(error));
+        }
+
+        if (m_outputBuffer.size() !=
+            fwrite(m_outputBuffer.c_str(), 1, m_outputBuffer.size(),
+                   m_fp.Get()))
+        {
+            int error = errno;
+            ThrowMsg(DPL::Exception, DPL::GetErrnoString(error));
+        }
+
+        if (-1 == TEMP_FAILURE_RETRY(fflush(m_fp.Get()))) {
+            int error = errno;
+            ThrowMsg(DPL::Exception, DPL::GetErrnoString(error));
+        }
+    }
+
+    void PrintfErrorMessage(const char* type,
+                            const std::string& message,
+                            bool verbosity)
+    {
+        if (verbosity) {
+            m_resultBuffer.append("\t\t\t<failure type=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(type));
+            m_resultBuffer.append("\" message=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(message));
+            m_resultBuffer.append("\"/>\n");
+        } else {
+            m_resultBuffer.append("\t\t\t<failure type=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(type));
+            m_resultBuffer.append("\"/>\n");
+        }
+    }
+
+    void PrintfIgnoredMessage(const char* type,
+                              const std::string& message,
+                              bool verbosity)
+    {
+        if (verbosity) {
+            m_resultBuffer.append("\t\t\t<skipped type=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(type));
+            m_resultBuffer.append("\" message=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(message));
+            m_resultBuffer.append("\"/>\n");
+        } else {
+            m_resultBuffer.append("\t\t\t<skipped type=\"");
+            m_resultBuffer.append(EscapeSpecialCharacters(type));
+            m_resultBuffer.append("\"/>\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, "&quot;");
+                i += 6;
+                break;
+
+            case '&':
+                s.erase(i, 1);
+                s.insert(i, "&amp;");
+                i += 5;
+                break;
+
+            case '<':
+                s.erase(i, 1);
+                s.insert(i, "&lt;");
+                i += 4;
+                break;
+
+            case '>':
+                s.erase(i, 1);
+                s.insert(i, "&gt;");
+                i += 4;
+                break;
+
+            case '\'':
+                s.erase(i, 1);
+                s.insert(i, "&#39;");
+                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=<filename> - 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<std::string> TestResultsCollectorBase::GetCollectorsNames()
+{
+    std::vector<std::string> 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 (file)
index 0000000..aaac7af
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_results_collector.h>
+#include <dpl/exception.h>
+#include <dpl/scoped_free.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/colors.h>
+#include <pcrecpp.h>
+#include <algorithm>
+#include <cstdio>
+#include <memory.h>
+#include <libgen.h>
+#include <cstring>
+#include <cstdlib>
+#include <dpl/utils/wrt_global_settings.h>
+
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(DPL::Test::TestRunner)
+
+namespace {
+
+std::string getXMLNode(xmlNodePtr node)
+{
+    std::string ret;
+    xmlChar * value = xmlNodeGetContent(node);
+    ret = std::string(reinterpret_cast<char*>(value));
+    xmlFree(value);
+    return ret;
+}
+
+}
+
+
+namespace DPL {
+namespace Test {
+namespace // anonymous
+{
+std::string BaseName(std::string aPath)
+{
+    ScopedFree<char> 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<std::string> & files)
+{
+    DECLARE_EXCEPTION_TYPE(DPL::Exception, XMLError)
+
+    const std::string idPath = "/test_definition/suite/set/testcase/@id";
+
+    bool success = true;
+    std::map<std::string, bool> 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<std::string, bool> & 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 type> --output=<output type> ...\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=<test id>\tStart from concrete test id");
+    fprintf(stderr, "  --group=<group name>\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=<xml file>\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=<group name>\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, "<p.dobrowolsk@samsung.com>\n");
+}
+
+int TestRunner::ExecTestRunner(int argc, char *argv[])
+{
+    std::vector<std::string> 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<std::string> 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 (file)
index 0000000..8e793e8
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <dpl/test/test_results_collector.h>
+#include <dpl/binary_queue.h>
+#include <dpl/exception.h>
+#include <dpl/scoped_free.h>
+#include <dpl/foreach.h>
+#include <dpl/colors.h>
+#include <pcrecpp.h>
+#include <algorithm>
+#include <cstdio>
+#include <memory.h>
+#include <libgen.h>
+#include <cstring>
+#include <cstdlib>
+#include <ctime>
+#include <unistd.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <dpl/utils/wrt_global_settings.h>
+
+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<int>(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<char> 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<const char *>(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<char*>(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 (file)
index 0000000..691966f
--- /dev/null
@@ -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 <unistd.h>
+#include <sys/file.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <dpl/test/test_runner_multiprocess.h>
+#include <poll.h>
+#include <limits.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+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 (file)
index 0000000..0ecf599
--- /dev/null
@@ -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<dpl/test/value_separated_policies.h>
+#include<dpl/foreach.h>
+#include<dpl/log/log.h>
+
+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<std::string> & )
+{
+    return false;
+}
+
+bool CSVParserPolicy::Validate(std::shared_ptr<std::vector<std::vector<std::string> > > & 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 (file)
index 0000000..4b53e27
--- /dev/null
@@ -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 <dpl/test/value_separated_tokens.h>
+
+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 (file)
index 0000000..828ca6c
--- /dev/null
@@ -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 (file)
index 0000000..33a5f9d
--- /dev/null
@@ -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 <string>
+
+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 (file)
index 0000000..71a77bd
--- /dev/null
@@ -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 <string>
+
+#include <dpl/string.h>
+
+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 (file)
index 0000000..1d93385
--- /dev/null
@@ -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 <dpl/string.h>
+#include <dpl/optional_typedefs.h>
+
+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<DPL::String>& getMimeTypesSupportedForIcon();
+    static const std::set<DPL::String>& getMimeTypesSupportedForStartFile();
+
+    typedef std::map<DPL::String, DPL::String> 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<DPL::String, DPL::String> 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 (file)
index 0000000..83290d0
--- /dev/null
@@ -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 <dirent.h>
+#include <sys/stat.h>
+
+#include <string>
+#include <sstream>
+#include <iterator>
+#include <memory>
+#include <vector>
+
+#include <dpl/exception.h>
+#include <dpl/string.h>
+
+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<std::input_iterator_tag, Path>
+    {
+    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<DIR> m_dir;
+        std::shared_ptr<Path> m_path;
+        std::shared_ptr<Path> 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<std::string> 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 (file)
index 0000000..71773cb
--- /dev/null
@@ -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 <vector>
+
+#include <dpl/string.h>
+#include <dpl/log/log.h>
+
+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<DPL::String> 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 (file)
index 0000000..de3d3aa
--- /dev/null
@@ -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 <dpl/string.h>
+#include <dpl/optional.h>
+#include <ostream>
+
+/*
+ * 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<DPL::String> m_micro;
+    DPL::Optional<DPL::String> m_optional;
+
+    void WacCertify(const DPL::String &major,
+                    const DPL::String &minor,
+                    const DPL::Optional<DPL::String> &micro,
+                    const DPL::Optional<DPL::String> &optional);
+
+  public:
+    explicit WidgetVersion(const DPL::String &str = DPL::String());
+    WidgetVersion(const DPL::String &major,
+                  const DPL::String &minor,
+                  const DPL::Optional<DPL::String> &micro,
+                  const DPL::Optional<DPL::String> &optional);
+
+    bool IsWac() const;
+    const DPL::String &Raw() const;
+
+    const DPL::String &Major() const;
+    const DPL::String &Minor() const;
+    const DPL::Optional<DPL::String> &Micro() const;
+    const DPL::Optional<DPL::String> &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 (file)
index 0000000..14407ae
--- /dev/null
@@ -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 (file)
index 0000000..165e167
--- /dev/null
@@ -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 <j.majnert@samsung.com>
+ * @brief       Common utility functions
+ */
+
+#ifndef _WRT_UTILITY_H_
+#define _WRT_UTILITY_H_
+
+#include <sys/stat.h>
+
+/**
+ * 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 (file)
index 0000000..1222eda
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/utils/bash_utils.h>
+#include <dpl/log/log.h>
+
+#include <string>
+
+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 (file)
index 0000000..522216a
--- /dev/null
@@ -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 <stddef.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fts.h>
+
+#include <sstream>
+#include <vector>
+
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/utils/folder_size.h>
+
+namespace Utils {
+size_t getFolderSize(const std::string& path)
+{
+    size_t size = 0;
+    FTS *fts;
+    FTSENT *ftsent;
+    char * const paths[] = { const_cast<char * const>(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<typename ... Rest>
+struct Pre;
+
+template<typename Postfix, typename ... Rest>
+struct Pre<Postfix, Rest ...>
+{
+    static const double value;
+    static std::string printSize(double fileSize)
+    {
+        if (fileSize >= Pre<Rest ...>::value) {
+            double now = fileSize / Pre<Rest ...>::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<Rest ...>::printSize(fileSize);
+        }
+    }
+};
+
+template<>
+struct Pre<>
+{
+    static const double value;
+    static std::string printSize(double /*fileSize*/)
+    {
+        return "0B";
+    }
+};
+
+const double Pre<>::value = 1.0;
+template<typename Postfix, typename ... Params> const double Pre<Postfix,
+                                                                 Params ...>::
+    value(Pre<>::value * stepSize);
+
+typedef Pre<PrefixGB, PrefixMB, PrefixKB, PrefixB> FolderSizeToStringType;
+} //anonymous namespace
+
+DPL::String fromFileSizeString(size_t fileSize)
+{
+    std::string output =
+        FolderSizeToStringType::printSize(static_cast<double>(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 (file)
index 0000000..18a72fe
--- /dev/null
@@ -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.
+ */
+#include <stddef.h>
+#include <set>
+#include <dpl/assert.h>
+#include <vector>
+
+#include <map>
+#include <xdgmime.h>
+
+#include <dpl/utils/mime_type_utils.h>
+
+const std::set<DPL::String>& MimeTypeUtils::getMimeTypesSupportedForIcon()
+{
+    static std::set<DPL::String> 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<DPL::String>& MimeTypeUtils::getMimeTypesSupportedForStartFile()
+{
+    static std::set<DPL::String> 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<DPL::String> 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;
+            }
+        }
+    }
+
+    // step 10 - sniff
+    std::string filePath = DPL::ToUTF8String(path);
+
+    std::string mime = xdg_mime_get_mime_type_for_file(filePath.c_str(), 0);
+    if (!mime.empty()) {
+        return DPL::FromASCIIString(mime);
+    }
+    return DPL::FromASCIIString("application/sniff");
+}
diff --git a/modules/utils/src/path.cpp b/modules/utils/src/path.cpp
new file mode 100644 (file)
index 0000000..0a41837
--- /dev/null
@@ -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 <dpl/utils/wrt_utility.h>
+#include <dpl/scoped_free.h>
+#include <dpl/errno_string.h>
+#include <dpl/file_input.h>
+#include <dpl/file_output.h>
+#include <dpl/copy.h>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+#include <unistd.h>
+#include <ftw.h>
+#include <sys/time.h>
+
+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<Path>(new Path(str));
+    m_dir = std::shared_ptr<DIR>(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<Path>(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<char> 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<std::string> 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<std::string>::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<unsigned long long>(tv.tv_sec) * 1000000ULL + static_cast<unsigned long long>(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 (file)
index 0000000..bd8650a
--- /dev/null
@@ -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 <stddef.h>
+#include <list>
+#include <memory>
+#include <set>
+#include <string>
+#include <dpl/utils/warp_iri.h>
+#include <dpl/string.h>
+#include <dpl/foreach.h>
+#include <idna.h>
+#include <istream>
+#include <iri.h>
+//#include <ValidatorCommon.h>
+
+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_struct, decltype(&iri_destroy)> 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<unsigned int>(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<std::string> 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 (file)
index 0000000..6ba7933
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/utils/widget_version.h>
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+#include <ctype.h>
+#include <list>
+
+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<ssize_t>(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<DPL::String> 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<DPL::String> 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<DPL::String> 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<DPL::String> &micro,
+                             const DPL::Optional<DPL::String> &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<DPL::String> &micro,
+                               const DPL::Optional<DPL::String> &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<DPL::String> &WidgetVersion::Micro() const
+{
+    return m_micro;
+}
+
+const DPL::Optional<DPL::String> &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 (file)
index 0000000..4f005c5
--- /dev/null
@@ -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 <stddef.h>
+#include <cstdlib>
+#include <cstring>
+#include <string>
+#include <sstream>
+#include <sys/utsname.h>
+#include <dpl/utils/wrt_global_settings.h>
+
+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 "<arch>_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 (file)
index 0000000..44044f2
--- /dev/null
@@ -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 <j.majnert@samsung.com>
+ * @brief       Implementation of some common utility functions
+ */
+#include <stddef.h>
+#include <fts.h>
+#include <string>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <dpl/log/log.h>
+#include <dpl/utils/wrt_utility.h>
+
+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<char * const>(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 (file)
index 0000000..269f37f
--- /dev/null
@@ -0,0 +1,141 @@
+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
+    dlog
+    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 (file)
index 0000000..1cf6773
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+
+#include <dpl/db/thread_database_support.h>
+#include <dpl/db/sql_connection.h>
+#include <dpl/mutex.h>
+#include <dpl/thread.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+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 (file)
index 0000000..4f65da5
--- /dev/null
@@ -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 <stddef.h>
+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 (file)
index 0000000..827f3cd
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES 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 <stddef.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/log/log.h>
+#include <libxml/xmlreader.h>
+#include <libxml/xmlstring.h>
+
+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<DPL::String> opt = str;
+    NormalizeString(opt);
+    str = *opt;
+}
+
+void NormalizeString (DPL::Optional<DPL::String>& txt, bool isTrimSpace)
+{
+    if (!!txt) {
+        std::string tmp = DPL::ToUTF8String(*txt);
+        const xmlChar* str = reinterpret_cast<const xmlChar*>(tmp.c_str());
+        if (!xmlCheckUTF8(str)) {
+            LogError("Not valid UTF8");
+            return;
+        }
+
+        int i = 0;
+        xmlChar* c;
+        while ((c = const_cast<xmlChar*>(xmlUTF8Strpos(str, i))) != NULL) {
+            if (!IsSpace(c)) {
+                break;
+            }
+            ++i;
+        }
+
+        xmlChar* tmpnew = xmlUTF8Strndup(c, xmlUTF8Strlen(c) + 1);
+        if (tmpnew == NULL) {
+            LogError("can't do xmlUTF*Strndup();");
+            return;
+        }
+
+        bool first = false;
+        xmlChar* s = tmpnew;
+        while ((c = const_cast<xmlChar*>(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<char*>(tmpnew));
+        xmlFree(tmpnew);
+    }
+}
+
+void NormalizeAndTrimSpaceString(DPL::OptionalString& txt)
+{
+    NormalizeString(txt, true);
+}
+
+#if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
+void NormalizeString(DPL::String& str, const unsigned int length,
+#if ENABLE(ADD_ELLIPSIS)
+                     bool showEllipsis
+#else
+                     bool /*showEllipsis*/
+#endif
+                    )
+{
+#if ENABLE(ADD_ELLIPSIS)
+    bool hasExceededMaxLength = false;
+    if (str.size() > length) {
+        hasExceededMaxLength = true;
+        str.resize(length);
+    }
+#else
+    if (str.size() > length) {
+        str.resize(length);
+    }
+#endif
+
+    DPL::Optional<DPL::String> opt = str;
+    NormalizeString(opt);
+    str = *opt;
+#if ENABLE(ADD_ELLIPSIS)
+    if (showEllipsis && hasExceededMaxLength && (str.size() == length)) {
+        str = DPL::FromUTF8String(DPL::ToUTF8String(str).append("..."));
+    }
+#endif
+}
+
+void NormalizeString(DPL::Optional<DPL::String>& str, const unsigned int length,
+#if ENABLE(ADD_ELLIPSIS)
+                     bool showEllipsis
+#else
+                     bool /*showEllipsis*/
+#endif
+                    )
+{
+#if ENABLE(ADD_ELLIPSIS)
+    bool hasExceededMaxLength = false;
+    if (!!str) {
+        if ((*str).size() > length) {
+            hasExceededMaxLength = true;
+            (*str).resize(length);
+        }
+#else
+    if (!!str) {
+        if ((*str).size() > length) {
+            (*str).resize(length);
+        }
+#endif
+
+        NormalizeString(str);
+#if ENABLE(ADD_ELLIPSIS)
+        if (showEllipsis && hasExceededMaxLength && ((*str).size() == length)) {
+            str = DPL::FromUTF8String(DPL::ToUTF8String(*str).append("..."));
+        }
+#endif
+    }
+}
+
+void NormalizeAndTrimSpaceString(DPL::OptionalString& str, const unsigned int length)
+{
+    if (!!str) {
+        if ((*str).size() > length) {
+            (*str).resize(length);
+        }
+        NormalizeString(str, true);
+    }
+}
+#endif //ELEMENT_ATTR_MAX_LENGTH
+
+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 !(*this == info);
+}
+
+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 !(*this == other);
+}
+
+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 !(*this == info);
+}
+
+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 !(*this == other);
+}
+} // namespace WrtDB
diff --git a/modules/widget_dao/dao/feature_dao.cpp b/modules/widget_dao/dao/feature_dao.cpp
new file mode 100644 (file)
index 0000000..15cd23f
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/wrt-dao-rw/feature_dao.h>
+#include <dpl/foreach.h>
+#include <dpl/db/orm.h>
+#include <orm_generator_wrt.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+
+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<DeviceCapabilities::DeviceCapName>(
+                                  DPL::FromUTF8String(*itdev)));
+
+                deviceCapID =
+                    select->GetSingleValue<DeviceCapabilities::DeviceCapID>();
+            } 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<int>(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<DeviceCapabilities::DeviceCapName>(
+                    DPL::FromUTF8String(*it)));
+            del->Execute();
+        }
+
+        // Unregister Feature
+        WRT_DB_DELETE(del, FeaturesList, &WrtDatabase::interface())
+        del->Where(Equals<FeaturesList::FeatureUUID>(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 (file)
index 0000000..ee188bd
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/wrt-dao-ro/feature_dao_read_only.h>
+#include <sstream>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/db/orm.h>
+#include <orm_generator_wrt.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+#include <dpl/wrt-dao-ro/plugin_dao_read_only.h>
+
+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<FeaturesList::FeatureName>(
+                          DPL::FromUTF8String(featureName)));
+
+        m_featureHandle = select->GetSingleValue<FeaturesList::FeatureUUID>();
+        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<FeaturesList::FeatureUUID>(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<FeaturesList::FeatureUUID>(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<FeaturesList::FeatureUUID>();
+
+        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<FeaturesList::FeatureName>(
+                          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<FeaturesList::FeatureUUID>(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<DeviceCapabilities::DeviceCapName>(
+                          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<FeatureDeviceCapProxy::FeatureUUID>(
+                               m_featureHandle));
+
+        DeviceCapabilitiesList devCap;
+
+        std::list<int> deviceIDs =
+            selectDevCP->GetValueList<FeatureDeviceCapProxy::DeviceCapID>();
+        FOREACH(devCId, deviceIDs)
+        {
+            WRT_DB_SELECT(selectDevC,
+                          DeviceCapabilities,
+                          &WrtDatabase::interface())
+            selectDevC->Where(Equals<DeviceCapabilities::DeviceCapID>(*devCId));
+
+            DPL::String devNames =
+                selectDevC->GetSingleValue<DeviceCapabilities::DeviceCapName>();
+
+            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<FeaturesList::PluginPropertiesId>(pluginHandle));
+
+        FeatureHandleListPtr handles(new FeatureHandleList);
+        FeatureHandleList ret =
+            select->GetValueList<FeaturesList::FeatureUUID>();
+
+        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<FeatureHandle,
+                                     std::string>(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<DevCapNameList>(Equal<FeatureDeviceCapProxy::DeviceCapID,
+                                           DeviceCapabilities::DeviceCapID>());
+
+        DeviceCapabilitiesMap devCap;
+
+        std::list< CustomRow<DevCapNameList> > rowList =
+            select->GetCustomRowList< DevCapNameList, CustomRow<DevCapNameList> >();
+        FOREACH(rowIt, rowList)
+        {
+            FeatureHandle featureHandle =
+                (*rowIt).GetColumnData<FeatureDeviceCapProxy::FeatureUUID>();
+            std::string devName =
+                DPL::ToUTF8String((*rowIt).GetColumnData<DeviceCapabilities::
+                                                             DeviceCapName>());
+            devCap.insert(std::pair<FeatureHandle, std::string>(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<FeaturesList::FeatureName>(apifeature));
+            featureUUID = select->GetSingleValue<FeaturesList::FeatureUUID>();
+        }
+
+        {
+            WRT_DB_SELECT(select,
+                          FeatureDeviceCapProxy,
+                          &WrtDatabase::interface())
+            select->Where(Equals<FeatureDeviceCapProxy::FeatureUUID>(
+                              featureUUID));
+            rows = select->GetRowList();
+        }
+
+        FOREACH(it, rows){
+            WRT_DB_SELECT(select, DeviceCapabilities, &WrtDatabase::interface())
+            select->Where(Equals<DeviceCapabilities::DeviceCapID>(
+                              it->Get_DeviceCapID()));
+            result.insert(select->
+                              GetSingleValue<DeviceCapabilities::DeviceCapName>());
+        }
+
+        return result;
+    } Catch(DPL::DB::SqlConnection::Exception::Base){
+        ReThrowMsg(FeatureDAOReadOnly::Exception::DatabaseError,
+                   "Failed to get device capability");
+    }
+}
+
+FeatureDAOReadOnly::FeatureMap
+FeatureDAOReadOnly::GetFeatures(const std::list<std::string>& featureNames)
+{
+    Try {
+        using namespace DPL::DB::ORM;
+        using namespace DPL::DB::ORM::wrt;
+
+        std::set<typename FeaturesList::FeatureName::ColumnType> nameList;
+        FOREACH(nm, featureNames) {
+            nameList.insert(DPL::FromUTF8String(*nm));
+        }
+
+        WRT_DB_SELECT(select, FeaturesList, &WrtDatabase::interface())
+        select->Where(In<FeaturesList::FeatureName>(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<FeatureHandle, FeatureData>(
+                                  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 (file)
index 0000000..ab55476
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/wrt-dao-ro/path_builder.h>
+#include <sstream>
+
+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 (file)
index 0000000..5b899c3
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/wrt-dao-rw/plugin_dao.h>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <orm_generator_wrt.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+
+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<WrtDB::DbWidgetHandle>(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<PluginProperties::PluginPropertiesId>(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<PluginProperties::PluginPropertiesId>(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 (file)
index 0000000..a90e013
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/wrt-dao-ro/plugin_dao_read_only.h>
+
+#include <sstream>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+#include <dpl/db/orm.h>
+#include <orm_generator_wrt.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+
+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<PluginProperties::PluginPropertiesId>(
+                          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<PluginProperties::PluginLibraryName>(
+                          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<PluginProperties::PluginLibraryName>(
+                          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<PluginProperties::PluginPropertiesId>();
+
+        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<PluginProperties::PluginPropertiesId>();
+
+        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<PluginDependencies::PluginPropertiesId>(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<PluginImplementedObjects::PluginObject>(
+                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<DPL::String> valueList = select->GetValueList<PluginImplementedObjects::PluginObject>();
+
+        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<PluginImplementedObjects::PluginPropertiesId>(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<PluginRequiredObjects::PluginPropertiesId>(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<PluginProperties::InstallationState>(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<PluginProperties::PluginPropertiesId>(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<PluginProperties::PluginPropertiesId>(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 (file)
index 0000000..fa6412a
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/wrt-dao-rw/property_dao.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <orm_generator_wrt.h>
+
+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<WidgetPreference::tizen_appid>(tzAppid),
+                       Equals<WidgetPreference::key_name>(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<WidgetPreference::tizen_appid>(tzAppid),
+                              Equals<WidgetPreference::key_name>(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 &regInfo)
+{
+    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 (file)
index 0000000..4916ebc
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/wrt-dao-ro/property_dao_read_only.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <orm_generator_wrt.h>
+
+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<DPL::DB::ORM::wrt::WidgetPreference::Row>
+ORMWidgetPreferenceList;
+typedef std::list<WidgetPropertyKey> 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<WidgetPreference::app_id>(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<WidgetPreference::app_id>(widgetHandle),
+                          Equals<WidgetPreference::key_name>(key)));
+
+        return select->GetSingleValue<WidgetPreference::readonly>();
+    }
+    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<WidgetPreference::app_id>(widgetHandle));
+        keyList = select->GetValueList<WidgetPreference::key_name>();
+
+        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<WidgetPreference::app_id>(widgetHandle),
+                          Equals<WidgetPreference::key_name>(key)));
+
+        ORMWidgetPropertyValue ormPropValue =
+            select->GetSingleValue<WidgetPreference::key_value>();
+
+        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 (file)
index 0000000..5fbb7d7
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+
+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 (executable)
index 0000000..487cb93
--- /dev/null
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT 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 <stddef.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+
+#include <sstream>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+#include <dpl/wrt-dao-rw/property_dao.h>
+#include <orm_generator_wrt.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+
+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<wrt::WidgetInfo::app_id>(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<WidgetInfo::tizen_appid>(fromAppId));
+
+        WidgetInfo::Row row = select->GetSingleRow();
+
+        //WidgetInfo::Row row;
+        row.Set_tizen_appid(toAppId);
+
+        WRT_DB_UPDATE(update, WidgetInfo, &WrtDatabase::interface())
+        update->Where(Equals<WidgetInfo::tizen_appid>(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<DbWidgetHandle> 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<DbWidgetHandle> 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<int>(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<WidgetInfo::tizen_appid>(tzAppId));
+        return select->GetSingleValue<WidgetInfo::app_id>();
+    } 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<int>(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<int>(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<wrt::WidgetFeature::app_id>(m_widgetHandle),
+                      Equals<wrt::WidgetFeature::name>(widgetFeature.name)));
+
+    auto row = select->GetSingleRow();
+    row.Set_rejected(widgetFeature.rejected);
+
+    WRT_DB_UPDATE(update, wrt::WidgetFeature, &WrtDatabase::interface())
+    update->Where(And(Equals<wrt::WidgetFeature::app_id>(m_widgetHandle),
+                      Equals<wrt::WidgetFeature::name>(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 <int>(
+                                     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<unsigned>(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()
+{
+    SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+    {
+        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<WidgetExternalLocations::app_id>(m_widgetHandle));
+        del->Execute();
+    }
+    SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to unregister external locations")
+}
+
+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<WidgetInfo::app_id>(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 (executable)
index 0000000..84a67ed
--- /dev/null
@@ -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 <stddef.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+#include <sstream>
+#include <dpl/foreach.h>
+#include <dpl/sstream.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/webruntime_database.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <dpl/wrt-dao-ro/widget_config.h>
+#include <dpl/wrt-dao-ro/feature_dao_read_only.h>
+#include <orm_generator_wrt.h>
+#include <LanguageTagsProvider.h>
+
+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<WidgetInfo::app_id>(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<WidgetInfo::app_id>(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<WidgetInfo::tizen_pkgid>(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<TizenAppId>& idList)
+{
+    LogDebug("Getting TizenAppId by pkgid : " << tzPkgid);
+    SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+    {
+        WRT_DB_SELECT(select, WidgetInfo, &WrtDatabase::interface())
+        select->Where(Equals<WidgetInfo::tizen_pkgid>(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<WidgetInfo::app_id>(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<WidgetInfo::tizen_appid>(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<WidgetInfo::widget_id>(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<WidgetInfo::tizen_appid>(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<WidgetInfo::tizen_pkgid>(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<WidgetInfo::tizen_appid>();
+    }
+    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<WidgetInfo::tizen_appid>();
+    }
+    SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get TizenAppIdList")
+}
+
+std::list<TizenAppId> WidgetDAOReadOnly::getTzAppIdList(const TizenPkgId tzPkgid){
+    std::list<TizenAppId> 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<WidgetInfo::tizen_pkgid>();
+    }
+    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<WidgetInfo::tizen_pkgid>();
+    }
+    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<LocalizedWidgetInfo::app_id>(m_widgetHandle),
+                Equals<LocalizedWidgetInfo::widget_locale>(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<WidgetFeature::app_id>(m_widgetHandle));
+
+        DbWidgetFeatureSet resultSet;
+        typedef std::list<WidgetFeature::Row> 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<wrt::WidgetFeature::app_id>(m_widgetHandle),
+                          Equals<wrt::WidgetFeature::name>(
+                              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<WidgetInfo::app_id>(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<WidgetInfo::tizen_appid>(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<WidgetExternalLocations::app_id>(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<WidgetCertificate::app_id>(m_widgetHandle),
+            Equals<WidgetCertificate::cert_source>(source)));
+
+    std::list<WidgetCertificate::Row> 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<AppType>(*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<DPL::String> WidgetDAOReadOnly::getVersion() const
+{
+    WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+    return row.Get_widget_version();
+}
+
+DPL::Optional<DPL::String> WidgetDAOReadOnly::getAuthorName() const
+{
+    WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+    return row.Get_author_name();
+}
+
+DPL::Optional<DPL::String> WidgetDAOReadOnly::getAuthorEmail() const
+{
+    WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+    return row.Get_author_email();
+}
+
+DPL::Optional<DPL::String> WidgetDAOReadOnly::getAuthorHref() const
+{
+    WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+    return row.Get_author_href();
+}
+
+DPL::Optional<DPL::String> 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<WidgetExtendedInfo::app_id>(m_widgetHandle));
+
+        WidgetExtendedInfo::Select::RowList rows = select->GetRowList();
+        if (rows.empty()) {
+            ThrowMsg(WidgetDAOReadOnly::Exception::WidgetNotExist,
+                     "Cannot find widget. Handle: " << m_widgetHandle);
+        }
+
+        return static_cast<time_t>(*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<WidgetExtendedInfo::app_id>(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<WidgetLocalizedIcon::app_id>(m_widgetHandle));
+
+        std::list<WidgetLocalizedIcon::Row> 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<wrt::WidgetIcon::app_id>(m_widgetHandle));
+        select->OrderBy(DPL::TypeListDecl<OrderingAscending<wrt::WidgetIcon::
+                                                                icon_id> >());
+
+        std::list<WidgetIcon::Row> 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<WidgetLocalizedStartFile::app_id>(
+                          m_widgetHandle));
+        select->OrderBy("start_file_id ASC");
+
+        std::list<WidgetLocalizedStartFile::Row> 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<WidgetStartFile::app_id>(m_widgetHandle));
+        select->OrderBy("start_file_id ASC");
+
+        std::list<WidgetStartFile::Row> 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<WidgetWindowModes::app_id>(m_widgetHandle));
+
+        return select->GetValueList<WidgetWindowModes::window_mode>();
+    }
+    SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get window modes")
+}
+
+std::string WidgetDAOReadOnly::getBaseFolder() const
+{
+    WidgetInfoRow row = getWidgetInfoRow(m_widgetHandle);
+    DPL::Optional<DPL::String> 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<WidgetCertificateFingerprint::app_id>(
+                          m_widgetHandle));
+        select->OrderBy("chainid");
+        WidgetCertificateFingerprint::Select::RowList rows =
+            select->GetRowList();
+
+        WidgetCertificateDataList outlCertificateData;
+        FOREACH(it, rows)
+        {
+            WidgetCertificateData data;
+
+            data.owner =
+                static_cast <WidgetCertificateData::Owner>(it->Get_owner());
+            data.type =
+                static_cast <WidgetCertificateData::Type>(it->Get_type());
+            data.chainId = it->Get_chainid();
+            DPL::Optional<DPL::String> md5 = it->Get_md5_fingerprint();
+            data.strMD5Fingerprint =
+                md5.IsNull() ? "" : DPL::ToUTF8String(*md5);
+            DPL::Optional<DPL::String> sha1 = it->Get_sha1_fingerprint();
+            data.strSHA1Fingerprint =
+                sha1.IsNull() ? "" : DPL::ToUTF8String(*sha1);
+            DPL::Optional<DPL::String> 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<WidgetCertificateFingerprint::app_id>(
+                                  m_widgetHandle),
+                              Equals<WidgetCertificateFingerprint::owner>(owner)),
+                          Equals<WidgetCertificateFingerprint::type>(type)));
+
+        WidgetCertificateFingerprint::Select::RowList rows =
+            select->GetRowList();
+
+        FingerPrintList keys;
+        FOREACH(it, rows)
+        {
+            DPL::Optional<DPL::String> sha1 = it->Get_sha1_fingerprint();
+            if (!sha1.IsNull()) {
+                keys.push_back(DPL::ToUTF8String(*sha1));
+            }
+            DPL::Optional<DPL::String> 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<WidgetCertificateFingerprint::app_id>(
+                                  m_widgetHandle),
+                              Equals<WidgetCertificateFingerprint::owner>(owner)),
+                          Equals<WidgetCertificateFingerprint::type>(type)));
+
+        WidgetCertificateFingerprint::Select::RowList rows =
+            select->GetRowList();
+
+        WidgetCertificateCNList out;
+        FOREACH(it, rows)
+        {
+            DPL::Optional<DPL::String> 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<WidgetWARPInfo::app_id>(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<WidgetAllowNavigation::app_id>(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<LocalizedWidgetInfo::app_id>(m_widgetHandle));
+        return select->GetValueList<LocalizedWidgetInfo::widget_locale>();
+    }
+    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<WidgetLocalizedIcon::app_id>(m_widgetHandle));
+    select->Distinct();
+    return select->GetValueList<WidgetLocalizedIcon::widget_locale>();
+}
+
+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<SettingsList::appId>(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<AppControlInfo::app_id>(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<WidgetAppControl::Disposition>(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<PkgType>(*result));
+}
+
+void WidgetDAOReadOnly::getEncryptedFileList(EncryptedFileList& filesList)
+const
+{
+    //TODO check widget existance
+    WRT_DB_SELECT(select, EncryptedResourceList, &WrtDatabase::interface())
+    select->Where(Equals<EncryptedResourceList::app_id>(m_widgetHandle));
+
+    typedef std::list<EncryptedResourceList::Row> 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<WidgetExtendedInfo::app_id>(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<WidgetExtendedInfo::app_id>(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<WidgetPrivilege::app_id>(m_widgetHandle));
+
+        return select->GetValueList<WidgetPrivilege::name>();
+    }
+    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<WidgetSecurityModelVersion>(*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 (file)
index 0000000..1296b28
--- /dev/null
@@ -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 <dpl/wrt-dao-ro/widget_dao_types.h>
+#include <dpl/log/log.h>
+
+namespace WrtDB {
+
+const std::map<std::string, Feature> 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 (file)
index 0000000..8caa49f
--- /dev/null
@@ -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 <dpl/db/thread_database_support.h>
+
+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 (executable)
index 0000000..d734efa
--- /dev/null
@@ -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 <set>
+#include <string>
+#include <map>
+#include <vector>
+#include <list>
+#include <memory>
+#include <dpl/optional_typedefs.h>
+
+namespace WrtDB {
+class PluginMetafileData
+{
+  public:
+    struct Feature
+    {
+        std::string m_name;
+        std::set<std::string> m_deviceCapabilities;
+
+        bool operator< (const Feature& obj) const
+        {
+            return m_name < obj.m_name;
+        }
+    };
+    typedef std::set<Feature> FeatureContainer;
+
+  public:
+
+    PluginMetafileData()
+    {}
+
+    std::string m_libraryName;
+    FeatureContainer m_featureContainer;
+};
+
+class PluginObjectsDAO
+{
+  public:
+    typedef std::set<std::string> Objects;
+    typedef std::shared_ptr<Objects> 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<WidgetAccessInfo> WidgetAccessInfoList;
+
+struct WidgetAllowNavigationInfo
+{
+    DPL::String scheme;
+    DPL::String host;
+};
+typedef std::list<WidgetAllowNavigationInfo> 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<DPL::String> WindowModeList;
+
+typedef std::list<DPL::String> PrivilegeList;
+
+typedef std::set<EncryptedFileInfo> 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<DbWidgetFeature> DbWidgetFeatureSet;
+
+/**
+ * @brief Default container with DbWidgetHandle's
+ */
+typedef std::list<DbWidgetHandle> DbWidgetHandleList;
+typedef std::list<TizenAppId> TizenAppIdList;
+typedef std::list<TizenPkgId> TizenPkgIdList;
+
+class WidgetDAOReadOnly; //forward declaration
+typedef std::shared_ptr<WidgetDAOReadOnly> WidgetDAOReadOnlyPtr;
+/**
+ * @brief Default container with WidgetDAOReadOnly
+ */
+typedef std::list<WidgetDAOReadOnlyPtr> 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<WidgetSetting> 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<WidgetAppControl> 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 (executable)
index 0000000..84bacc3
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES 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 <string>
+#include <set>
+#include <list>
+#include <map>
+#include <dpl/optional_typedefs.h>
+#include <dpl/string.h>
+#include <dpl/platform.h>
+#include <ctype.h>
+
+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);
+#if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
+void NormalizeString(DPL::String& str, const unsigned int length, bool showEllipsis = false);
+void NormalizeString(DPL::OptionalString& str, const unsigned int length, bool showEllipsis = false);
+void NormalizeAndTrimSpaceString(DPL::OptionalString& str, const unsigned int length);
+#endif // ELEMENT_ATTR_MAX_LENGTH
+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<Feature> 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<Privilege> 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<Icon> IconsList;
+
+    struct LocalizedData
+    {
+        DPL::OptionalString name;
+        DPL::OptionalString shortName;
+
+        DPL::OptionalString description;
+
+        DPL::OptionalString license;
+        DPL::OptionalString licenseFile;
+        DPL::OptionalString licenseHref;
+    };
+    typedef std::map<DPL::String, LocalizedData> 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<Preference> PreferencesList;
+    typedef std::set<DPL::String> 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<AccessInfo> 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<Setting> 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 <DPL::String> m_uriList;
+        std::set <DPL::String> m_mimeList;
+        Disposition m_disposition;
+        unsigned m_index;
+
+        bool operator==(const AppControlInfo&) const;
+        bool operator!=(const AppControlInfo&) const;
+    };
+
+    typedef std::list<AppControlInfo> AppControlInfoList;
+
+    struct LiveboxInfo
+    {
+        LiveboxInfo() { }
+
+        struct BoxSize
+        {
+            DPL::String m_size;
+            DPL::String m_preview;
+            DPL::String m_useDecoration;
+        };
+        typedef BoxSize BoxSizeInfo;
+        typedef std::list<BoxSizeInfo> 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<std::pair<DPL::String, DPL::String> > 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<LiveboxInfo> OptionalLiveboxInfo;
+    typedef std::list<OptionalLiveboxInfo> LiveboxList;
+
+    enum IconSectionType
+    {
+        DefaultIcon =0,
+        SmallIcon
+    };
+
+    typedef std::set<std::pair<IconSectionType, DPL::String>> IconSet;
+    typedef std::list<DPL::String> CapabilityList;
+    typedef std::set<std::pair<DPL::String, DPL::String>> DisplayNameSet;
+
+    struct AccountProvider
+    {
+        AccountProvider() :
+            m_multiAccountSupport(false)
+        { }
+
+        bool m_multiAccountSupport;
+        IconSet m_iconSet;
+        DisplayNameSet m_displayNameSet;
+        CapabilityList m_capabilityList;
+    };
+
+    typedef std::list<DPL::OptionalString> DependsPkgList;
+    typedef std::set<DPL::String> 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<AllowNavigationInfo> 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<Metadata> MetadataList;
+
+    struct ImeAppInfo
+    {
+        DPL::String uuid;
+        typedef std::set<DPL::String> LanguageList;
+        LanguageList languageList;
+    };
+    typedef std::list<ImeAppInfo> 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<ServiceAppInfo> 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;
+
+    // Ambient Support(true, false)
+    DPL::OptionalString ambient;
+
+    // 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 (file)
index 0000000..f366012
--- /dev/null
@@ -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 <set>
+#include <string>
+#include <dpl/exception.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+#include "feature_model.h"
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+
+namespace WrtDB {
+// TODO: Move to feature_model.h
+typedef std::set<DPL::String> 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<std::string> DeviceCapabilitiesList;
+    typedef std::multimap<FeatureHandle, std::string> DeviceCapabilitiesMap;
+    typedef std::map<FeatureHandle, std::string> NameMap;
+    typedef std::map<FeatureHandle, FeatureData> 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<std::string>& 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 (file)
index 0000000..8698d4a
--- /dev/null
@@ -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 <dpl/event/model.h>
+#include <dpl/event/property.h>
+#include <memory>
+#include <string>
+#include <list>
+#include <set>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+namespace WrtDB {
+typedef int FeatureHandle;
+typedef std::list<FeatureHandle> FeatureHandleList;
+typedef std::shared_ptr<FeatureHandleList> FeatureHandleListPtr;
+
+typedef int FeatureSetHandle;
+typedef std::list<FeatureSetHandle> FeatureSetHandleList;
+
+typedef struct {
+    std::string featureName;
+    DbPluginHandle pluginHandle;
+} FeatureData;
+
+class FeatureModel : public DPL::Event::Model
+{
+  public:
+    DPL::Event::Property<FeatureHandle, DPL::Event::PropertyReadOnly> FHandle;
+    DPL::Event::Property<std::string> Name;
+
+    DPL::Event::Property<std::set<std::string> > DeviceCapabilities;
+    DPL::Event::Property<DbPluginHandle> PHandle;
+
+    FeatureModel(FeatureHandle handle) :
+        FHandle(this, handle),
+        Name(this),
+        DeviceCapabilities(this),
+        PHandle(this, -1)
+    {}
+
+    void SetData(const std::string& name,
+                 const std::set<std::string>& deviceCapabilities,
+                 const DbPluginHandle& pluginHandle)
+    {
+        Name.SetWithoutLock(name);
+        DeviceCapabilities.SetWithoutLock(deviceCapabilities);
+        PHandle.SetWithoutLock(pluginHandle);
+    }
+};
+
+typedef std::shared_ptr<FeatureModel> 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 (file)
index 0000000..c8bd592
--- /dev/null
@@ -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 <string>
+#include <list>
+
+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.1";
+}
+
+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 (file)
index 0000000..4ea6a4f
--- /dev/null
@@ -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 <string>
+#include <dpl/noncopyable.h>
+
+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 (file)
index 0000000..3be2441
--- /dev/null
@@ -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 <string>
+#include <list>
+#include <memory>
+#include <dpl/exception.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+namespace WrtDB {
+typedef std::list<DbPluginHandle> PluginHandleList;
+typedef std::set<DbPluginHandle> PluginHandleSet;
+typedef std::list<std::string> ImplementedObjectsList;
+typedef std::shared_ptr<PluginHandleSet> 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<int>(state);
+    }
+
+    static PluginInstallationState ToState(int state)
+    {
+        return static_cast<PluginDAOReadOnly::PluginInstallationState>(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 (file)
index 0000000..88e308a
--- /dev/null
@@ -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 <list>
+#include <dpl/string.h>
+#include <dpl/exception.h>
+#include <dpl/db/orm.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+namespace WrtDB {
+namespace PropertyDAOReadOnly {
+typedef DPL::String WidgetPropertyKey;
+typedef DPL::OptionalString WidgetPropertyValue;
+
+typedef std::list<WidgetPropertyKey> WidgetPropertyKeyList;
+
+struct WidgetPreferenceRow {
+    int appId;
+    TizenAppId tizen_appid;
+    WidgetPropertyKey key_name;
+    WidgetPropertyValue key_value;
+    DPL::OptionalInt readonly;
+};
+
+typedef std::list<WidgetPreferenceRow> 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 (file)
index 0000000..67c88a9
--- /dev/null
@@ -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 <dpl/thread.h>
+#include <dpl/mutex.h>
+
+extern DPL::Mutex g_wrtDbQueriesMutex;
+
+#define WRT_DB_INTERNAL(tlsCommand, InternalType, interface)                 \
+    static DPL::ThreadLocalVariable<InternalType> *tlsCommand##Ptr = NULL; \
+    {                                                                        \
+        DPL::Mutex::ScopedLock lock(&g_wrtDbQueriesMutex);                   \
+        if (!tlsCommand##Ptr) {                                            \
+            static DPL::ThreadLocalVariable<InternalType> tmp;               \
+            tlsCommand##Ptr = &tmp;                                        \
+        }                                                                    \
+    }                                                                        \
+    DPL::ThreadLocalVariable<InternalType> &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 (file)
index 0000000..c452814
--- /dev/null
@@ -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 <string>
+#include <dpl/string.h>
+
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/path_builder.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+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 (executable)
index 0000000..c82995d
--- /dev/null
@@ -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 <time.h>
+#include <list>
+#include <string>
+#include <dpl/availability.h>
+#include <dpl/string.h>
+#include <dpl/exception.h>
+#include <dpl/db/orm.h>
+#include <dpl/optional_typedefs.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/wrt-dao-ro/property_dao_read_only.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+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<WidgetCertificateData> WidgetCertificateDataList;
+
+typedef DPL::String Locale;
+typedef std::set<Locale> LocaleSet;
+typedef std::list<std::string> 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<Locale,
+                     StartFileProperties> StartFilePropertiesForLocalesMap;
+    struct LocalizedStartFile
+    {
+        DPL::String path;
+        StartFilePropertiesForLocalesMap propertiesForLocales;
+    };
+
+    typedef std::list<LocalizedIcon> LocalizedIconList;
+    typedef std::list<LocalizedStartFile> 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<std::string> 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 <std::string> WidgetCertificateCNList;
+typedef std::list<DPL::String> LanguageTagList;
+typedef std::list<std::string> HostList;
+typedef std::list<std::string> 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<WidgetLocalizedIconRow> WidgetLocalizedIconList;
+
+    struct WidgetIconRow
+    {
+        int iconId;
+        int appId;
+        DPL::String iconSrc;
+        DPL::OptionalInt iconWidth;
+        DPL::OptionalInt iconHeight;
+    };
+    typedef std::list<WidgetIconRow> WidgetIconList;
+
+    struct WidgetStartFileRow
+    {
+        int startFileId;
+        int appId;
+        DPL::String src;
+    };
+    typedef std::list<WidgetStartFileRow> WidgetStartFileList;
+
+    struct WidgetLocalizedStartFileRow
+    {
+        int startFileId;
+        int appId;
+        DPL::String widgetLocale;
+        DPL::String type;
+        DPL::String encoding;
+    };
+    typedef std::list<WidgetLocalizedStartFileRow> 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<TizenAppId> 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 (file)
index 0000000..6d6e171
--- /dev/null
@@ -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 <list>
+#include <memory>
+#include <map>
+#include <dpl/string.h>
+
+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<std::string, Feature> 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 (file)
index 0000000..1702433
--- /dev/null
@@ -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 <dpl/wrt-dao-ro/common_dao_types.h>
+
+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 (file)
index 0000000..6ee312a
--- /dev/null
@@ -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 <dpl/wrt-dao-ro/feature_dao_read_only.h>
+
+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 (file)
index 0000000..0b53eef
--- /dev/null
@@ -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 <dpl/wrt-dao-ro/plugin_dao_read_only.h>
+
+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 (file)
index 0000000..7e3f215
--- /dev/null
@@ -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 <dpl/wrt-dao-ro/property_dao_read_only.h>
+
+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 &regInfo);
+} // 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 (executable)
index 0000000..d205ccf
--- /dev/null
@@ -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 <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <list>
+#include <string>
+#include <sys/time.h>
+#include <ctime>
+#include <cstdlib>
+#include <dpl/availability.h>
+#include <dpl/exception.h>
+#include <dpl/db/orm.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/wrt-dao-rw/property_dao.h>
+
+namespace WrtDB {
+class WidgetDAO : public WidgetDAOReadOnly
+{
+  public:
+    typedef std::list<DPL::String> 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<DbWidgetHandle> handle =
+            DPL::Optional<DbWidgetHandle>());
+    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<DbWidgetHandle> handle =
+            DPL::Optional<DbWidgetHandle>());
+    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 (executable)
index 0000000..38587b7
--- /dev/null
@@ -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 (file)
index 0000000..09ac57e
--- /dev/null
@@ -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 <dpl/db/orm_generator.h>
+#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 (file)
index 0000000..7e20d8d
--- /dev/null
@@ -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 (file)
index 0000000..4d31747
--- /dev/null
@@ -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 (file)
index 0000000..f2a4a2e
--- /dev/null
@@ -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 (file)
index 0000000..1b69679
--- /dev/null
@@ -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 <dpl/db/orm_macros.h>
+
+#include "wrt_db_definitions"
diff --git a/modules/widget_interface_dao/CMakeLists.txt b/modules/widget_interface_dao/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6e4c409
--- /dev/null
@@ -0,0 +1,46 @@
+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
+    dlog
+    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 (file)
index 0000000..1d66ed8
--- /dev/null
@@ -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 <wrt-commons/widget-interface-dao/widget_interface_dao.h>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dpl/db/sql_connection.h>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+#include <dpl/string.h>
+#include <dpl/wrt-dao-ro/property_dao_read_only.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <dpl/wrt-dao-ro/widget_config.h>
+#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<Properties::key>(DPL::FromUTF8String(key)));
+        std::list<Properties::Row> 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<Properties::key>(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<Properties::key>(DPL::FromUTF8String(key)));
+        bool readonly = select.GetSingleValue<Properties::readonly>();
+        if (readonly) {
+            ThrowMsg(Exception::LocalStorageValueNoModifableException,
+                     "Cannot delete item. Item is readonly");
+        }
+        Properties::Delete deleteItem(&m_databaseInterface);
+        deleteItem.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
+        deleteItem.Execute();
+    }
+    SQL_CONNECTION_EXCEPTION_HANDLER_END("Cannot delete item");
+}
+
+DPL::Optional<std::string> WidgetInterfaceDAO::getValue(
+    const std::string& key) const
+{
+    SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
+    {
+        Properties::Select select(&m_databaseInterface);
+        select.Where(Equals<Properties::key>(DPL::FromUTF8String(key)));
+        std::list<DPL::String> value =
+            select.GetValueList<Properties::value>();
+        if (value.empty()) {
+            return DPL::Optional<std::string>();
+        }
+        return DPL::Optional<std::string>(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<Properties::readonly>(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<DPL::String> list =
+            select.GetValueList<Properties::key>();
+        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<DPL::String> list = select.GetValueList<Properties::key>();
+        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 (file)
index 0000000..8b35344
--- /dev/null
@@ -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 <string>
+#include <dpl/db/thread_database_support.h>
+#include <dpl/db/orm_interface.h>
+
+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<std::string> 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<WidgetInterfaceDAO> 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 (file)
index 0000000..87a3e05
--- /dev/null
@@ -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 <dpl/db/orm_generator.h>
+#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 (file)
index 0000000..d33ec48
--- /dev/null
@@ -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 (file)
index 0000000..85f627d
--- /dev/null
@@ -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 (file)
index 0000000..b4ce0b6
--- /dev/null
@@ -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 <dpl/db/orm_macros.h>
+
+#include "widget_interface_db_definitions"
diff --git a/packaging/wrt-commons.spec b/packaging/wrt-commons.spec
new file mode 100644 (file)
index 0000000..f97ef63
--- /dev/null
@@ -0,0 +1,146 @@
+#git:framework/web/wrt-commons
+Name:       wrt-commons
+Summary:    Wrt common library
+Version:    0.2.196_w8
+Release:    1
+Group:      Development/Libraries
+License:    Apache-2.0
+URL:        N/A
+Source0:    %{name}-%{version}.tar.gz
+BuildRequires:  cmake
+BuildRequires:  pkgconfig(ecore)
+BuildRequires:  pkgconfig(appcore-efl)
+BuildRequires:  pkgconfig(capi-appfw-application)
+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 (file)
index 0000000..50227c7
--- /dev/null
@@ -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 (file)
index 0000000..ea9cfb3
--- /dev/null
@@ -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 (file)
index 0000000..5629f99
--- /dev/null
@@ -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 <glib.h>
+#include <glib-object.h>
+
+#endif // GLIB_INTERFACE_H
diff --git a/tests/common/include/loop_control.h b/tests/common/include/loop_control.h
new file mode 100644 (file)
index 0000000..b58fb5c
--- /dev/null
@@ -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 (file)
index 0000000..5c690c2
--- /dev/null
@@ -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 <glib_interface.h>
+#include <loop_control.h>
+#include <dpl/log/log.h>
+
+#include <dpl/framework_efl.h>
+
+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 (file)
index 0000000..44d2321
--- /dev/null
@@ -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 (file)
index 0000000..48e5394
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..42ffe3a
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+
+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 (file)
index 0000000..d887ca0
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/address.h>
+
+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 (file)
index 0000000..cd8931d
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/binary_queue.h>
+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<const char *>(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 (file)
index 0000000..f71d418
--- /dev/null
@@ -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 <functional>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/bind.h>
+
+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<void()> 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<void(int, double)> 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<int(int, double)> 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 (file)
index 0000000..08d66df
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/foreach.h>
+#include <vector>
+#include <set>
+#include <list>
+
+RUNNER_TEST_GROUP_INIT(DPL)
+
+static const size_t testContainerSize = 1024;
+
+template<typename Container>
+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<size_t> temporaryList();
+std::list<size_t> temporaryList()
+{
+    ++numberOfCallsToTemporaryList;
+    std::list<size_t> list;
+    for (size_t i = 0; i < testContainerSize; i++) {
+        list.push_back(i);
+    }
+    return list;
+}
+
+static size_t numberOfCallsToTemporaryVector = 0;
+std::vector<size_t> temporaryVector();
+std::vector<size_t> temporaryVector()
+{
+    ++numberOfCallsToTemporaryVector;
+    std::vector<size_t> vector;
+    for (size_t i = 0; i < testContainerSize; i++) {
+        vector.push_back(i);
+    }
+    return vector;
+}
+
+static size_t numberOfCallsToTemporarySet = 0;
+std::set<size_t> temporarySet();
+std::set<size_t> temporarySet()
+{
+    ++numberOfCallsToTemporarySet;
+    std::set<size_t> 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<size_t> vector;
+    std::list<size_t> list;
+    std::set<size_t> 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 (file)
index 0000000..3299357
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/exception.h>
+#include <iostream>
+
+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 (file)
index 0000000..34e32fd
--- /dev/null
@@ -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 <functional>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/once.h>
+#include <dpl/waitable_event.h>
+#include <dpl/waitable_handle.h>
+#include <dpl/thread.h>
+#include <dpl/atomic.h>
+#include <memory>
+
+RUNNER_TEST_GROUP_INIT(DPL)
+
+namespace // anonymous
+{
+int 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<MyThread> 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 (file)
index 0000000..7c09645
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/scope_guard.h>
+
+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 (file)
index 0000000..f2a3b4b
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/scoped_array.h>
+
+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<char> 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<char> 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<char> 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<char> 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 (file)
index 0000000..3549fed
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/scoped_close.h>
+
+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 (file)
index 0000000..8cf0c3c
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/scoped_dir.h>
+
+#include <cstdio>
+#include <sstream>
+#include <cstdlib>
+
+#include <unistd.h>
+
+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 (file)
index 0000000..7667a9e
--- /dev/null
@@ -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 <cstdio>
+#include <cerrno>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/scoped_fclose.h>
+
+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 (file)
index 0000000..25bd6d6
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/scoped_free.h>
+#include <malloc.h>
+
+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<void> 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<void> 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<void> 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 (file)
index 0000000..af17bac
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/scoped_ptr.h>
+
+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<char> 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<char> 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<char> 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<char> 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 (file)
index 0000000..c93b365
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/lexical_cast.h>
+#include <dpl/semaphore.h>
+#include <dpl/thread.h>
+#include <dpl/log/log.h>
+#include <string>
+#include <ctime>
+
+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::string>(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 (file)
index 0000000..7bbf8de
--- /dev/null
@@ -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 <vector>
+#include <string>
+#include <list>
+#include <map>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/serialization.h>
+
+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<unsigned char> 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<std::string> 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<int> vec;
+    vec.push_back(134);
+    vec.push_back(265);
+    std::list<bool> list;
+    list.push_back(true);
+    list.push_back(false);
+    std::pair<int, unsigned> pair;
+    pair.first = -23;
+    pair.second = 1234;
+    std::map<int, std::string> map;
+    map.insert(std::pair<int, std::string>(45, "ALA MA CZARNEGO KOTA"));
+    map.insert(std::pair<int, std::string>(-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<int> 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<bool> 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<int, unsigned> test_pair;
+    DPL::Deserialization::Deserialize(stream, test_pair);
+    RUNNER_ASSERT(test_pair.first == pair.first &&
+                  test_pair.second == pair.second);
+    std::map<int, std::string> 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<std::string, std::vector<TestClass*> > map;
+    std::vector<TestClass*> 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<std::string, std::vector<TestClass*> >("KEY1", vec));
+    map.insert(std::pair<std::string, std::vector<TestClass*> >("KEY2", vec));
+    BinaryStream stream;
+
+    DPL::Serialization::Serialize(stream, map);
+
+    std::map<std::string, std::vector<TestClass*> > test_map;
+    DPL::Deserialization::Deserialize(stream, test_map);
+    RUNNER_ASSERT(map.size() == test_map.size());
+    std::vector<TestClass*> 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 (file)
index 0000000..8e59075
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/shared_ptr.h>
+
+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<char> ptr;
+
+    RUNNER_ASSERT(!ptr);
+    RUNNER_ASSERT(!!!ptr);
+    RUNNER_ASSERT(ptr == DPL::SharedPtr<char>());
+}
+
+/*
+Name: SharedPtr_NonZero
+Description: Tests behaviour of not null shared pointer
+Expected: pointer should imitate null pointer
+*/
+RUNNER_TEST(SharedPtr_NonZero)
+{
+    DPL::SharedPtr<char> ptr(new char(7));
+
+    RUNNER_ASSERT(ptr);
+    RUNNER_ASSERT(!!ptr);
+    RUNNER_ASSERT(ptr != DPL::SharedPtr<char>());
+}
+
+/*
+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<char> ptr1(new char(7));
+    DPL::SharedPtr<char> 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<char> 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<char> ptr1(new char(7));
+    DPL::SharedPtr<char> 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<char> 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 (file)
index 0000000..b17d583
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/single_instance.h>
+
+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 (file)
index 0000000..b7596ef
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/static_block.h>
+
+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 (file)
index 0000000..e124376
--- /dev/null
@@ -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 <stdlib.h>
+#include <cmath>
+#include <cstring>
+#include <vector>
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <dpl/string.h>
+#include <dpl/sstream.h>
+
+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<char**>(&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<typename DelimiterType>
+void String_TokenizeReal(const DelimiterType& delimiter)
+{
+    DPL::String str(L".##..abc.#.");
+    std::vector<DPL::String> tokens;
+    DPL::Tokenize(str, delimiter, std::back_inserter(tokens));
+
+    std::vector<DPL::String> 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<std::string> tokens;
+    DPL::Tokenize(std::string("abc.def"), '.', std::back_inserter(tokens));
+    std::vector<std::string> expectedTokens;
+    expectedTokens.push_back("abc");
+    expectedTokens.push_back("def");
+
+    RUNNER_ASSERT(tokens == expectedTokens);
+}
+
+template <typename TemplateArgumentCharTraits>
+void TestInStreams(
+    std::basic_string<typename TemplateArgumentCharTraits::char_type,
+                      TemplateArgumentCharTraits> argumentInString,
+    std::basic_string<typename TemplateArgumentCharTraits::char_type,
+                      TemplateArgumentCharTraits> argumentResultString)
+{
+    typedef std::basic_string<typename TemplateArgumentCharTraits::char_type,
+                              TemplateArgumentCharTraits>
+    String;
+    std::basic_istringstream<typename TemplateArgumentCharTraits::char_type,
+                             TemplateArgumentCharTraits>
+    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 <typename TemplateArgumentCharTraits>
+void TestOutStreams(
+    std::basic_string<typename TemplateArgumentCharTraits::char_type,
+                      TemplateArgumentCharTraits> argumentInString,
+    std::basic_string<typename TemplateArgumentCharTraits::char_type,
+                      TemplateArgumentCharTraits> argumentResultString)
+{
+    typedef std::basic_string<typename TemplateArgumentCharTraits::char_type,
+                              TemplateArgumentCharTraits>
+    String;
+
+    std::basic_ostringstream<typename TemplateArgumentCharTraits::char_type,
+                             TemplateArgumentCharTraits>
+    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<std::char_traits<char> >("1 1.1 1.1 test", "test");
+    TestInStreams<std::char_traits<wchar_t> >(L"1 1.1 1.1 test", L"test");
+    TestInStreams<DPL::CharTraits>(L"1 1.1 1.1 test", L"test");
+    TestOutStreams<std::char_traits<char> >("test", "11.11.1test");
+    TestOutStreams<std::char_traits<wchar_t> >(L"test", L"11.11.1test");
+    TestOutStreams<DPL::CharTraits>(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<std::string> 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 (file)
index 0000000..8eec1f0
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/thread.h>
+#include <dpl/log/log.h>
+
+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<Foo> 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 (file)
index 0000000..b3e6285
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/type_list.h>
+
+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<int, char, int[64]>::Type TestTypeList1;
+    typedef DPL::TypeListDecl<int>::Type TestTypeList2;
+    typedef DPL::TypeListDecl<>::Type TestTypeList3;
+    typedef DPL::TypeList<int, TestTypeList1> 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 (file)
index 0000000..a456d3c
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+
+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 (file)
index 0000000..c62accb
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/zip_input.h>
+#include <dpl/foreach.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/abstract_waitable_output_adapter.h>
+#include <dpl/binary_queue.h>
+#include <dpl/scoped_array.h>
+#include <dpl/copy.h>
+#include <dpl/log/log.h>
+
+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<char> 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 (file)
index 0000000..88c0e24
--- /dev/null
@@ -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 (file)
index 0000000..6c60a17
--- /dev/null
@@ -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 (file)
index 0000000..729b4a3
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <wrt-commons/certificate-dao/certificate_dao.h>
+
+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 (file)
index 0000000..d606b03
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/foreach.h>
+#include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
+#include <wrt-commons/custom-handler-dao-ro/common_dao_types.h>
+
+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 (file)
index 0000000..f01355c
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-rw/feature_dao.h>
+#include <dpl/wrt-dao-rw/plugin_dao.h>
+#include <dpl/wrt-dao-ro/wrt_db_types.h>
+
+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<std::string> fs0(4);
+//    RUNNER_ASSERT(FeatureDAOReadOnly::GetFeatures(fs0).size() == 0);
+//
+//    std::list<std::string> fs1(4);
+//    fs1.push_front("feature");
+//    fs1.push_front("feature2");
+//    RUNNER_ASSERT(FeatureDAOReadOnly::GetFeatures(fs1).size() == 2);
+//    std::list<std::string> fs2(4);
+//    fs2.push_front("feature");
+//    fs2.push_front("feature2");
+//    RUNNER_ASSERT(FeatureDAOReadOnly::GetFeatures(fs2).size() == 1);
+
+    std::list<std::string> 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<const char *> 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<const char *> 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<const char *> 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<const char *> 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 (file)
index 0000000..091d8ed
--- /dev/null
@@ -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 <list>
+#include <dpl/test/test_runner.h>
+#include <dpl/foreach.h>
+#include <dpl/exception.h>
+#include <dpl/wrt-dao-rw/plugin_dao.h>
+//#include <plugin_install/plugin_objects.h>
+#include <dpl/wrt-dao-ro/wrt_db_types.h>
+#include <dpl/log/log.h>
+
+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<const char *> 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 <empty>");
+        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<const char *> 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<const char *> 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 (file)
index 0000000..8ff2ad6
--- /dev/null
@@ -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 <list>
+#include <map>
+#include <dpl/test/test_runner.h>
+#include <dpl/foreach.h>
+#include <dpl/exception.h>
+#include <dpl/wrt-dao-rw/property_dao.h>
+#include <dpl/wrt-dao-ro/wrt_db_types.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+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<three_field> prefList;
+        std::list<three_field>::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<WrtDB::TizenAppId, WidgetPropertyKeyList *> prefsKeyMap;
+        prefsKeyMap.insert(std::pair<WrtDB::TizenAppId, WidgetPropertyKeyList *>(
+                               L"tizenid201", &orig_2000));
+        prefsKeyMap.insert(std::pair<WrtDB::TizenAppId, WidgetPropertyKeyList *>(
+                               L"tizenid202", &orig_2001));
+        prefsKeyMap.insert(std::pair<WrtDB::TizenAppId, WidgetPropertyKeyList *>(
+                               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 (file)
index 0000000..fc4e46e
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <wrt-commons/security-origin-dao/security_origin_dao.h>
+
+
+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 100755 (executable)
index 0000000..bbcc249
--- /dev/null
@@ -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 <list>
+#include <cstdlib>
+#include <cstdio>
+#include <string>
+#include <algorithm>
+#include <dpl/test/test_runner.h>
+#include <dpl/foreach.h>
+#include <dpl/exception.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/wrt-dao-ro/wrt_db_types.h>
+#include <dpl/string.h>
+#include <wrt_plugin_export.h>
+#include <LanguageTagsProvider.h>
+
+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<typename Exception, typename Function>
+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<exceptionType>([](){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<DPL::String> 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<DPL::String> 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<DPL::String,DPL::String>(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<DPL::String,DPL::String>(s1, s2));
+    a11.m_label.push_back(std::pair<DPL::String,DPL::String>(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<DPL::String,DPL::String>(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 (file)
index 0000000..fae5e11
--- /dev/null
@@ -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 <list>
+#include <cstdlib>
+#include <cstdio>
+#include <string>
+#include <algorithm>
+#include <dpl/test/test_runner.h>
+#include <dpl/foreach.h>
+#include <dpl/exception.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/wrt-dao-ro/wrt_db_types.h>
+#include <dpl/string.h>
+#include <wrt_plugin_export.h>
+#include <wrt-commons/widget-interface-dao/widget_interface_dao.h>
+
+#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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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 (file)
index 0000000..ae3c7cd
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
+
+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 (executable)
index 0000000..4bb3f0e
--- /dev/null
@@ -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 (file)
index 0000000..837679e
--- /dev/null
@@ -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 (file)
index 0000000..4ed6191
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+
+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 (file)
index 0000000..b7ebafb
--- /dev/null
@@ -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 (file)
index 0000000..0d1963b
--- /dev/null
@@ -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 (file)
index 0000000..da79427
--- /dev/null
@@ -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 (file)
index 0000000..cac41cc
--- /dev/null
@@ -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 <dpl/db/orm_macros.h>
+
+#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 (file)
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 (file)
index 0000000..39bb1b7
--- /dev/null
@@ -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 <dpl/db/orm_generator.h>
+#undef ORM_GENERATOR_DATABASE_NAME
+
+#endif
diff --git a/tests/db/test_orm.cpp b/tests/db/test_orm.cpp
new file mode 100644 (file)
index 0000000..c7c9ea9
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/foreach.h>
+#include <dpl/db/thread_database_support.h>
+#include <generator_dpl_orm_test.h>
+#include <sstream>
+
+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<typename ContainerType1, typename ContainerType2>
+bool ContainerContentsEqual(const ContainerType1& container1,
+                            const ContainerType2& container2)
+{
+    using namespace DPL::DB::ORM::dpl_orm_test::TestTableInsert;
+    typedef std::set<typename ContainerType1::value_type> Set1;
+    typedef std::set<typename ContainerType2::value_type> 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<typename T>
+std::list<T> makeList(const T& a, const T& b)
+{
+    std::list<T> 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<TestTable::ColumnInt>(8));
+        int result;
+        RUNNER_ASSERT_MSG((result =
+                               *select.GetSingleValue<TestTable::ColumnOptInt>())
+                          == 6, "Got " <<
+                          result);
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Equals<TestTable::ColumnInt>(8));
+        DPL::String result;
+        RUNNER_ASSERT_MSG((result =
+                               *select.GetSingleValue<TestTable::ColumnOptText>(
+                                   )) == L"seven",
+                          "Got " << result);
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Equals<TestTable::ColumnInt>(8));
+        int result;
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt>(
+                                   )) == 8, "Got " << result);
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Equals<TestTable::ColumnInt>(8));
+        int result;
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
+                                   )) == 9, "Got " << result);
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Equals<TestTable::ColumnInt>(8));
+        DPL::String result;
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnText>(
+                                   )) == L"ten", "Got " << result);
+    }
+
+    //Where on each column
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Equals<TestTable::ColumnOptInt>(6));
+        int result;
+        RUNNER_ASSERT_MSG((result =
+                               *select.GetSingleValue<TestTable::ColumnOptInt>())
+                          == 6, "Got " <<
+                          result);
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Equals<TestTable::ColumnOptText>(DPL::String(L"seven")));
+        DPL::String result;
+        RUNNER_ASSERT_MSG((result =
+                               *select.GetSingleValue<TestTable::ColumnOptText>(
+                                   )) == L"seven",
+                          "Got " << result);
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Equals<TestTable::ColumnInt>(8));
+        int result;
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt>(
+                                   )) == 8, "Got " << result);
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Equals<TestTable::ColumnInt2>(9));
+        int result;
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
+                                   )) == 9, "Got " << result);
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Equals<TestTable::ColumnText>(L"ten"));
+        DPL::String result;
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnText>(
+                                   )) == 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<TestTable::ColumnInt>(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<TestTable::ColumnOptText>(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<TestTable::ColumnInt>(3));
+        std::list<TestTable::Row> 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<TestTable::ColumnOptText>(DPL::String(L"seven")));
+        std::list<TestTable::Row> 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<TestTable::ColumnInt>(99));
+        std::list<TestTable::Row> 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<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
+        RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
+                                                                     ColumnInt>(),
+                                             makeList(99, 99)));
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
+        RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
+                                                                     ColumnInt2>(),
+                                             makeList(11, 13)));
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
+        RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
+                                                                     ColumnText>(),
+                                             makeList(DPL::String(L"twelve"),
+                                                      DPL::String(L"fourteen"))));
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
+        RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
+                                                                     ColumnOptText>(),
+                                             makeList(DPL::Optional<DPL::String>
+                                                          ::Null,
+                                                      DPL::Optional<DPL::String>
+                                                          ::Null)));
+    }
+
+    //Where on each column
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
+        RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
+                                                                     ColumnInt2>(),
+                                             makeList(11, 13)));
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Is<TestTable::ColumnOptText>(DPL::Optional<DPL::String>::
+                                                      Null));
+        RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
+                                                                     ColumnInt2>(),
+                                             makeList(11, 13)));
+    }
+    {
+        TestTable::Select select(interface.get());
+        select.Where(Is<TestTable::ColumnInt>(99));
+        RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
+                                                                     ColumnInt2>(),
+                                             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<int> resultList = select1.GetValueList<TestTableInsert::ColumnInt>();
+    RUNNER_ASSERT_MSG(resultList.empty(),
+                      "Returned list has wrong size: " << resultList.size());
+
+    std::list<TestTableInsert::Row> 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<OrderingAscending<TestTableDelete::
+                                                                ColumnInt2> >());
+    std::list<TestTableDelete::Row> list = selectStart.GetRowList();
+    std::list<TestTableDelete::Row> originalList = list;
+
+    std::vector<TestTableDelete::Row> 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<TestTableDelete::ColumnOptInt>(1),
+                      Equals<TestTableDelete::ColumnOptText>(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<TestTableDelete::ColumnOptInt>(6),
+                      Equals<TestTableDelete::ColumnOptText>(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<TestTableDelete::ColumnInt2>(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<TestTableDelete::ColumnOptInt>(6),
+                      Equals<TestTableDelete::ColumnText>(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<TestTableDelete::ColumnOptText>(DPL::Optional<DPL::String>
+                                                         ::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<TestTableDelete::Row>::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<TestTable::ColumnInt>(8));
+        RUNNER_ASSERT_MSG((result =
+                               *select.GetSingleValue<TestTable::ColumnOptInt>())
+                          == 6, "Got " <<
+                          result);
+
+        select.Where(Equals<TestTable::ColumnInt>(3));
+        RUNNER_ASSERT_MSG((result =
+                               *select.GetSingleValue<TestTable::ColumnOptInt>())
+                          == 1, "Got " <<
+                          result);
+
+        select.Where(Equals<TestTable::ColumnInt>(8));
+        RUNNER_ASSERT_MSG((result =
+                               *select.GetSingleValue<TestTable::ColumnOptInt>())
+                          == 6, "Got " <<
+                          result);
+
+        select.Where(Equals<TestTable::ColumnInt>(3));
+        RUNNER_ASSERT_MSG((result =
+                               *select.GetSingleValue<TestTable::ColumnOptInt>())
+                          == 1, "Got " <<
+                          result);
+    }
+
+    {
+        TestTable::Select select(interface.get());
+        int result;
+        select.Where(And(Equals<TestTable::ColumnInt>(99),
+                         Equals<TestTable::ColumnText>(L"fourteen")));
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
+                                   )) == 13, "Got " << result);
+
+        select.Where(And(Equals<TestTable::ColumnInt>(99),
+                         Equals<TestTable::ColumnText>(L"twelve")));
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
+                                   )) == 11, "Got " << result);
+
+        select.Where(And(Equals<TestTable::ColumnInt>(99),
+                         Equals<TestTable::ColumnText>(L"fourteen")));
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
+                                   )) == 13, "Got " << result);
+
+        select.Where(And(Equals<TestTable::ColumnInt>(99),
+                         Equals<TestTable::ColumnText>(L"twelve")));
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
+                                   )) == 11, "Got " << result);
+    }
+
+    {
+        TestTable::Select select(interface.get());
+        int result;
+        select.Where(And(Equals<TestTable::ColumnText>(L"fourteen"),
+                         Equals<TestTable::ColumnInt>(99)));
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
+                                   )) == 13, "Got " << result);
+
+        select.Where(And(Equals<TestTable::ColumnText>(L"twelve"),
+                         Equals<TestTable::ColumnInt>(99)));
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
+                                   )) == 11, "Got " << result);
+
+        select.Where(And(Equals<TestTable::ColumnText>(L"fourteen"),
+                         Equals<TestTable::ColumnInt>(99)));
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
+                                   )) == 13, "Got " << result);
+
+        select.Where(And(Equals<TestTable::ColumnText>(L"twelve"),
+                         Equals<TestTable::ColumnInt>(99)));
+        RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
+                                   )) == 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<TestTableInsert::Row> 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<TestTableInsert::ColumnInt2>(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<TestTableInsert::ColumnInt2>(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<TestTableInsert::ColumnInt2>(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<TestTableJoin1::TestText,
+                              TestTableJoin2::TestText2,
+                              DPL::TypeListGuard>::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<JoinColumns>(Equal<TestTableJoin1::TestID,
+                                   TestTableJoin2::TestID>());
+    std::list<CustomRow<JoinColumns> > rowlist =
+        select.GetCustomRowList<JoinColumns, CustomRow<JoinColumns> >();
+
+    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<TestTableJoin1::TestText>());
+        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<TestTableJoin2::TestText2>());
+        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<JoinColumns>(Equal<TestTableJoin1::TestNumber,
+                                    TestTableJoin2::TestID>());
+    rowlist = select2.GetCustomRowList<JoinColumns, CustomRow<JoinColumns> >();
+
+    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<JoinColumns>(Equal<TestTableJoin1::TestID,
+                                    TestTableJoin2::TestText1>());
+    rowlist = select3.GetCustomRowList<JoinColumns, CustomRow<JoinColumns> >();
+    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<TestTableJoin1::TestText>());
+        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<TestTableJoin2::TestText2>());
+        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<TestTableJoin1::TestText,
+                              TestTableJoin3::TestText33,
+                              DPL::TypeListGuard>::Type JoinTables2;
+    TestTableJoin1::Select select4(interface.get());
+    select4.Join<JoinTables2>(Equal<TestTableJoin1::TestNumber,
+                                    TestTableJoin3::Value3>());
+    std::list<CustomRow<JoinTables2> > rowlist2 =
+        select4.GetCustomRowList<JoinTables2, CustomRow<JoinTables2> >();
+    RUNNER_ASSERT_MSG(
+        rowlist2.size() == 4, "Expected 4 rows while received: " <<
+        rowlist.size());
+    cnt = 0;
+    DPL::Optional<DPL::String> optext;
+    FOREACH(rowit, rowlist2)
+    {
+        cnt++;
+
+        text =
+            DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin1::TestText>());
+        // 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<TestTableJoin3::TestText33>();
+        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<TestTableJoin1::TestText,
+                              TestTableJoin2::TestText2,
+                              TestTableJoin3::TestText33,
+                              DPL::TypeListGuard>::Type Join3Tables;
+    TestTableJoin1::Select select5(interface.get());
+    select5.Join<Join3Tables>(Equal<TestTableJoin1::TestID,
+                                    TestTableJoin2::TestID>());
+    select5.Join<Join3Tables>(Equal<TestTableJoin1::TestID,
+                                    TestTableJoin3::TestID>());
+    std::list<CustomRow<Join3Tables> > rowlist3tab =
+        select5.GetCustomRowList<Join3Tables, CustomRow<Join3Tables> >();
+    RUNNER_ASSERT_MSG(
+        rowlist3tab.size() == 3, "Expected 3 rows while received: " <<
+        rowlist3tab.size());
+    cnt = 0;
+    FOREACH(rowit, rowlist3tab)
+    {
+        cnt++;
+
+        text =
+            DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin1::TestText>());
+        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<TestTableJoin2::TestText2>());
+        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<TestTableJoin3::TestText33>();
+        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<OrderingAscending<TestTableJoin3::
+                                                               Value3>,
+                                         OrderingDescending<TestTableJoin3::
+                                                                TestText33>,
+                                         OrderingAscending<TestTableJoin3::
+                                                               TestID> >());
+
+        std::list<TestTableJoin3::Row> result = select.GetRowList();
+        std::list<TestTableJoin3::Row>::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 (file)
index 0000000..20907fa
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/db/sql_connection.h>
+#include <dpl/db/naive_synchronization_object.h>
+#include <memory>
+#include <dpl/log/log.h>
+#include <sstream>
+#include <string>
+#include <cstdlib>
+#include <ctime>
+
+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<unsigned long>(m_prefix);
+            valueStream << "_";
+            valueStream << static_cast<unsigned long>(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<DPL::Thread> 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<int8_t>(-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>((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<int32_t>(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<int64_t>(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<float>(-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<double>(-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 (file)
index 0000000..4a1f338
--- /dev/null
@@ -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 (file)
index 0000000..94b3d67
--- /dev/null
@@ -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 (file)
index 0000000..cabdf90
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#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<TimeoutEvent>::Touch();
+    DPL::Event::ControllerEventHandler<QuitEvent>::Touch();
+
+    DPL::Event::ControllerEventHandler<TimeoutEvent>::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<QuitEvent>::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 (file)
index 0000000..3c7ffe9
--- /dev/null
@@ -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 <string>
+#include <dpl/event/controller.h>
+#include <dpl/generic_event.h>
+
+DECLARE_GENERIC_EVENT_0(QuitEvent)
+DECLARE_GENERIC_EVENT_0(TimeoutEvent)
+
+class DBusTest :
+    private DPL::Event::Controller<DPL::TypeListDecl<QuitEvent,
+                                                     TimeoutEvent>::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 (file)
index 0000000..4dfd0b4
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+
+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 (file)
index 0000000..15a7153
--- /dev/null
@@ -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 <string>
+#include <dpl/test/test_runner.h>
+#include <dpl/event/event_listener.h>
+#include <dpl/dbus/exception.h>
+#include <dpl/dbus/connection.h>
+#include <dpl/dbus/interface.h>
+#include <dpl/dbus/server.h>
+#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 =
+    "<?xml version='1.0'?>"
+    "<node>"
+    "  <interface name='" + interfaceName + "'>"
+                                            "    <method name='" +
+    methodNameEcho + "'>"
+                     "      <arg type='s' name='challenge' direction='in'/>"
+                     "      <arg type='s' name='response' direction='out'/>"
+                     "    </method>"
+                     "    <method name='"
+    + methodNameQuit + "'>"
+                       "    </method>"
+                       "  </interface>"
+                       "</node>";
+
+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<std::string>
+                (dbusInterfaceName, dbusMethodGetId);
+        RUNNER_ASSERT(!getId().empty());
+    } catch (const DPL::DBus::Exception& ex) {
+        RUNNER_ASSERT_MSG(false, ex.DumpToString());
+    }
+}
+
+class RegisterServiceListener :
+    public DPL::Event::EventListener<DPL::DBus::ConnectionEvents::
+                                         ServiceNameAcquiredEvent>
+{
+  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<DPL::DBus::ConnectionEvents::
+                                                 ServiceNameAcquiredEvent>::
+            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<std::string, std::string>
+                (interfaceName, methodNameEcho);
+        auto response = echo(challenge);
+
+        testService->createMethodProxy<void>(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 (file)
index 0000000..510e4c5
--- /dev/null
@@ -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 <string>
+#include <dpl/dbus/connection.h>
+#include <dpl/dbus/object.h>
+#include <dpl/dbus/interface.h>
+#include <dpl/dbus/dispatcher.h>
+#include <loop_control.h>
+
+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 =
+    "<?xml version='1.0'?>"
+    "<node>"
+    "  <interface name='" + interfaceName + "'>"
+                                            "    <method name='" +
+    methodNameEcho + "'>"
+                     "      <arg type='s' name='challenge' direction='in'/>"
+                     "      <arg type='s' name='response' direction='out'/>"
+                     "    </method>"
+                     "    <method name='"
+    + methodNameQuit + "'>"
+                       "    </method>"
+                       "  </interface>"
+                       "</node>";
+}
+
+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 (file)
index 0000000..08fa4fa
--- /dev/null
@@ -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 (file)
index 0000000..4ed6191
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+
+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 (file)
index 0000000..5308720
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/event/controller.h>
+#include <dpl/thread.h>
+#include <dpl/generic_event.h>
+#include <dpl/waitable_handle.h>
+#include <dpl/waitable_event.h>
+#include <dpl/type_list.h>
+#include <dpl/application.h>
+#include <dpl/atomic.h>
+#include <list>
+#include <vector>
+#include <memory>
+
+RUNNER_TEST_GROUP_INIT(DPL)
+
+namespace {
+    unsigned int seed = time(NULL);
+}
+
+class IntController :
+    public DPL::Event::Controller<DPL::TypeListDecl<int>::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<DPL::TypeListDecl<DoneSignalEvent>::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<DPL::TypeListDecl<char, short, int, long,
+                                                    unsigned char,
+                                                    unsigned short,
+                                                    unsigned int, unsigned long,
+                                                    float, double,
+                                                    StrangeStruct>::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<DPL::TypeListDecl<TouchInThread>::Type>,
+    private DPL::Event::Controller<DPL::TypeListDecl<TouchedControllerSignal>::
+                                       Type>
+{
+  public:
+    typedef DPL::Event::Controller<DPL::TypeListDecl<TouchInThread>::Type>
+    PublicController;
+    typedef DPL::Event::Controller<DPL::TypeListDecl<TouchedControllerSignal>::
+                                       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<TestController> ControllerPtr;
+typedef std::shared_ptr<DPL::Thread> ThreadPtr;
+typedef std::vector<ControllerPtr> ControllerList;
+typedef std::list<ThreadPtr> ThreadList;
+
+DECLARE_GENERIC_EVENT_0(QuitEvent)
+class QuitController :
+    public DPL::Event::Controller<DPL::TypeListDecl<QuitEvent>::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<TestContext> TestContextPtr;
+TestContextPtr testContextPtr;
+
+DECLARE_GENERIC_EVENT_0(StartSendEvent)
+DECLARE_GENERIC_EVENT_0(RandomEvent)
+class TestController :
+    public DPL::Event::Controller<DPL::TypeListDecl<RandomEvent,
+                                                    StartSendEvent>::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<int>(testContextPtr->controllers.size());
+            testContextPtr->controllers.at(id)->DPL::Event::
+                ControllerEventHandler<RandomEvent>::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<StartSendEvent>::
+            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 (file)
index 0000000..d221fb9
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/generic_event.h>
+#include <dpl/event/event_listener.h>
+#include <dpl/event/event_support.h>
+#include <dpl/application.h>
+#include <dpl/event/controller.h>
+#include <dpl/log/log.h>
+
+DECLARE_GENERIC_EVENT_0(TestEvent)
+
+class TestListener : public DPL::Event::EventListener<TestEvent>
+{
+  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<TestEvent>
+{
+  public:
+    void TestEmitEvent()
+    {
+        EmitEvent(TestEvent());
+    }
+};
+
+DECLARE_GENERIC_EVENT_0(QuitEvent)
+
+class QuitController :
+    public DPL::Event::Controller<DPL::TypeListDecl<QuitEvent>::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<int>
+{
+  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 (file)
index 0000000..460cfee
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/application.h>
+#include <dpl/event/controller.h>
+#include <dpl/log/log.h>
+#include <dpl/event/inter_context_delegate.h>
+#include <dpl/thread.h>
+#include <dpl/waitable_event.h>
+#include <dpl/assert.h>
+#include <dpl/mutex.h>
+#include <dpl/type_list.h>
+#include <memory>
+RUNNER_TEST_GROUP_INIT(DPL)
+
+const int IntVal = 123;
+const std::string StringVal = "someString";
+
+typedef DPL::Event::ICDelegate<> GetNothingDlpType;
+typedef DPL::Event::ICDelegate<int> GetIntDlgType;
+typedef DPL::Event::ICDelegate<int, std::string> 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<DPL::TypeListDecl<GetNothingEvent,
+                                                    GetIntEvent,
+                                                    GetIntAndStringEvent>::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<TestContextFreeClass>
+{
+  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<GetNothingEvent>::
+            PostEvent(
+            getNothingEvent);
+
+        GetIntEvent getIntEvent(
+            makeICDelegate(
+                &TestContextFreeClass::OnIntReceive));
+        m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
+            PostEvent(
+            getIntEvent);
+
+        GetIntAndStringEvent getIntAndStringEvent(
+            makeICDelegate(
+                &TestContextFreeClass::OnIntAndStringReceive));
+        m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>
+            ::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<ICTestController> ICTestControllerPtr;
+typedef std::shared_ptr<TestContextFree> TestContextFreePtr;
+typedef std::shared_ptr<TestRunnerInThread> TestRunnerInThreadPtr;
+typedef std::shared_ptr<DPL::Thread> ThreadPtr;
+
+DPL::Mutex mutex;
+std::list<TestContextFreePtr> frees;
+std::list<ICTestControllerPtr> ctrls;
+std::list<TestRunnerInThreadPtr> frees_threads;
+std::list<ThreadPtr> ctrls_threads;
+}
+
+class TestContextFree : public DPL::Event::ICDelegateSupport<TestContextFree>
+{
+  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<GetNothingEvent>::
+                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<GetIntEvent>::
+                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<GetNothingEvent>::
+            PostEvent(
+            getNothingEvent);
+    }
+
+    void StartTestOnInt()
+    {
+        GetIntEvent getIntEvent(
+            makeICDelegate(
+                &TestContextFree::OnIntReceive));
+        m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
+            PostEvent(
+            getIntEvent);
+    }
+
+    void StartTestOnIntAndString()
+    {
+        GetIntAndStringEvent getIntAndStringEvent(
+            makeICDelegate(
+                &TestContextFree::OnIntAndStringReceive));
+        m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>
+            ::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<DPL::TypeListDecl<ReuseCountEvent>::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<ReuseCountEvent>::PostEvent(
+                event);
+        }
+    }
+
+    int m_reuseCount;
+};
+
+class ReuseTestContextFreeClass :
+    protected DPL::Thread,
+    public DPL::Event::ICDelegateSupport<ReuseTestContextFreeClass>
+{
+  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<ReuseCountEvent>::
+            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 (file)
index 0000000..2760932
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/event/property.h>
+#include <dpl/event/model.h>
+#include <string>
+
+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<std::string>
+    Caption;
+
+    DPL::Event::Property<std::string>
+    Testproperty0;
+
+    DPL::Event::Property<std::string, DPL::Event::PropertyReadOnly>
+    Testproperty1;
+
+    DPL::Event::Property<std::string, DPL::Event::PropertyReadWrite>
+    Testproperty2;
+
+    DPL::Event::Property<std::string, DPL::Event::PropertyReadWrite,
+                         DPL::Event::PropertyStorageCached> Testproperty3;
+
+    DPL::Event::Property<std::string, DPL::Event::PropertyReadWrite,
+                         DPL::Event::PropertyStorageDynamic> Testproperty4;
+
+    DPL::Event::Property<int, DPL::Event::PropertyReadOnly,
+                         DPL::Event::PropertyStorageDynamicCached>
+    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<std::string> &event);
+void OnNameChanged(const DPL::Event::PropertyEvent<std::string> &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 (file)
index 0000000..3fdd256
--- /dev/null
@@ -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 (file)
index 0000000..be10866
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/tests/files_localization/files/icon2 b/tests/files_localization/files/icon2
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/files_localization/files/one b/tests/files_localization/files/one
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/files_localization/files/two.html b/tests/files_localization/files/two.html
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/files_localization/test_localization.cpp b/tests/files_localization/test_localization.cpp
new file mode 100644 (file)
index 0000000..ae4925a
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+
+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 (file)
index 0000000..d163d1d
--- /dev/null
@@ -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 <dpl/log/log.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/static_block.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/localization/w3c_file_localization.h>
+#include <LanguageTagsProvider.h>
+
+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<DPL::String> 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<DPL::String> 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<DPL::String> 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<DPL::String> 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<DPL::String> 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<DPL::String> 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<DPL::String> 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<DPL::String> 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<DPL::String> 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<DPL::String> 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<DPL::String> result = W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
+            name,
+            DPL::String(L"dummy"));
+
+    RUNNER_ASSERT(result.IsNull());
+}
+
+RUNNER_TEST(test12_getFilePathInWidgetPackageFromUrl)
+{
+    WrtDB::TizenAppId name = L"tizenid202";
+
+    DPL::Optional<DPL::String> 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<DPL::String> 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<DPL::String> 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<DPL::String> 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 (file)
index 0000000..29c3806
--- /dev/null
@@ -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 (file)
index 0000000..9a90b43
--- /dev/null
@@ -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 (file)
index 0000000..4ed6191
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+
+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 (file)
index 0000000..57dfe2d
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+#include <wrt-commons/i18n-dao-ro/i18n_database.h>
+#include <wrt-commons/i18n-dao-ro/i18n_dao_read_only.h>
+
+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 (file)
index 0000000..fb3fee7
--- /dev/null
@@ -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 (file)
index 0000000..295ca7c
--- /dev/null
@@ -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 <dpl/log/log.h>
+#include <dpl/test/test_runner.h>
+#include <vconf.h>
+
+#include <LanguageTagsProvider.h>
+
+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 (file)
index 0000000..366e961
--- /dev/null
@@ -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 (file)
index 0000000..430cccf
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+
+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 (file)
index 0000000..ece6879
--- /dev/null
@@ -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 (file)
index 0000000..42ffe3a
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+
+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 (file)
index 0000000..6dfc30d
--- /dev/null
@@ -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 <dpl/test/test_runner_child.h>
+#include <dpl/log/log.h>
+#include <unistd.h>
+#include <vector>
+#include <sys/types.h>
+#include <signal.h>
+
+
+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 (file)
index 0000000..fcac88e
--- /dev/null
@@ -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 <dpl/test/test_runner_multiprocess.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+#include <list>
+
+namespace {
+std::list<std::string> split_string(std::string str, std::string delimiter)
+{
+    size_t pos = 0;
+    std::string token;
+    std::list<std::string> 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<std::string> 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<std::string>::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<std::string> 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<std::string>::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 (file)
index 0000000..8e74faa
--- /dev/null
@@ -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 <cstring>
+#include <string>
+
+#include <dpl/test/abstract_input_reader.h>
+#include <dpl/abstract_input.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/binary_queue.h>
+#include <dpl/optional.h>
+
+using namespace DPL;
+
+namespace {
+
+// TOKENIZER
+
+class DigitTokenizer : public AbstractInputTokenizer<int>
+{
+public:
+    DigitTokenizer() : m_valid(true) {}
+
+    std::unique_ptr<int> GetNextToken()
+    {
+        typedef AbstractInputTokenizer<int>::Exception::TokenizerError TokenizerError;
+
+        std::unique_ptr<int> 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<int>(buffer)));
+        return token;
+    }
+
+    void Reset(std::shared_ptr<AbstractInput> ia)
+    {
+        AbstractInputTokenizer<int>::Reset(ia);
+        m_valid = true;
+    }
+
+    bool IsStateValid()
+    {
+        return true;
+    }
+
+private:
+    bool m_valid;
+};
+
+// PARSER
+
+class SumatorParser : public AbstractInputParser<int, int>
+{
+public:
+    SumatorParser() : m_sum(0) {}
+
+    void ConsumeToken(std::unique_ptr<int> && token)
+    {
+        m_sum += (*token - '0');
+    }
+
+    bool IsStateValid()
+    {
+        return true;
+    }
+
+    int GetResult() const
+    {
+        return m_sum;
+    }
+
+private:
+    int m_sum;
+};
+
+// READER
+
+class Sumator : public AbstractInputReader<int, int>
+{
+public:
+    Sumator(std::shared_ptr<AbstractInput> ia)
+        : AbstractInputReader<int, int>(ia,
+            std::unique_ptr<ParserBase>(new SumatorParser()),
+            std::unique_ptr<TokenizerBase>(new DigitTokenizer()))
+    {}
+};
+
+}
+
+RUNNER_TEST_GROUP_INIT(AbstractInputReader)
+
+RUNNER_TEST(AbstractInputReader_ByteSumatorInstance_Sum)
+{
+    const std::string data("1234567890");
+    std::shared_ptr<AbstractInput> mem(new BinaryQueue());
+    dynamic_cast<BinaryQueue*>(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<AbstractInput> mem(new BinaryQueue());
+    dynamic_cast<BinaryQueue*>(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 (file)
index 0000000..46405f9
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/test/process_pipe.h>
+#include <dpl/binary_queue.h>
+#include <dpl/log/log.h>
+
+#include <cstring>
+
+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 (file)
index 0000000..af17c2a
--- /dev/null
@@ -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<dpl/test/value_separated_reader.h>
+#include<dpl/abstract_input.h>
+#include<dpl/test/test_runner.h>
+
+#include<string>
+
+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<AbstractInput> mem(new BinaryQueue());
+    dynamic_cast<BinaryQueue*>(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<AbstractInput> mem(new BinaryQueue());
+        dynamic_cast<BinaryQueue*>(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 (file)
index 0000000..6f1a1ff
--- /dev/null
@@ -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 <dpl/test_runner.h>
+#include <dpl/serialization.h>
+#include <dpl/caller.h>
+
+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<unsigned char> 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 (file)
index 0000000..dd208b6
--- /dev/null
@@ -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 <dpl/test_runner.h>
+#include <dpl/crypto_hash.h>
+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 (file)
index 0000000..09990b7
--- /dev/null
@@ -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 <dpl/test_runner.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/abstract_waitable_output_adapter.h>
+#include <dpl/message_queue.h>
+#include <dpl/binary_queue.h>
+#include <dpl/copy.h>
+#include <dpl/log.h>
+#include <dpl/application.h>
+#include <dpl/controller.h>
+#include <dpl/generic_event.h>
+
+DECLARE_GENERIC_EVENT_0(QuitEvent)
+
+class QuitController :
+    public DPL::Controller<DPL::TypeListDecl<QuitEvent>::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 (file)
index 0000000..20eed04
--- /dev/null
@@ -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 <stdlib.h>
+#include <ctime>
+#include <sys/shm.h>
+#include <dpl/semaphore.h>
+#include <dpl/test_runner.h>
+#include <dpl/thread.h>
+#include <dpl/controller.h>
+#include <dpl/generic_event.h>
+#include <dpl/log.h>
+#include <dpl/shared_object.h>
+#include <dpl/shared_property.h>
+#include <memory>
+
+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<int, int, char, int[64]>::Type TestTypeList;
+typedef DPL::TypeListDecl<int, int, char, int[63]>::Type TestTypeList2;
+typedef DPL::TypeListDecl<int, int, char, int[63], int>::Type TestTypeList3;
+
+typedef SharedObject<TestTypeList> TestSharedObject;
+typedef SharedObject<TestTypeList2> TestSharedObject2;
+typedef SharedObject<TestTypeList3> TestSharedObject3;
+
+typedef std::shared_ptr<TestSharedObject> TestSharedObjectPtr;
+
+const int INIT_EVENT = 0;
+const int DESTROY_EVENT = 1;
+
+int g_values[TestTypeList::Size];
+
+/*
+ * helper listening controller
+ */
+template <typename SharedType>
+class ListeningController :
+    public DPL::Controller<DPL::TypeListDecl<int>::Type>
+{
+  public:
+    explicit ListeningController(DPL::WaitableEvent* waitable);
+    ~ListeningController();
+
+    virtual void OnEventReceived(const int &event);
+
+    virtual void OnEvent(const int /*event*/) {}
+
+  protected:
+    std::shared_ptr<SharedType> m_so;
+    DPL::Thread m_thread;
+    DPL::WaitableEvent* m_waitable;
+};
+
+template <typename SharedType>
+ListeningController<SharedType>::ListeningController(
+    DPL::WaitableEvent* waitable) :
+    m_waitable(waitable)
+{
+    Touch();
+    m_thread.Run();
+    SwitchToThread(&m_thread);
+    PostEvent(INIT_EVENT);
+}
+
+template <typename SharedType>
+ListeningController<SharedType>::~ListeningController()
+{
+    m_thread.Quit();
+}
+
+template <typename SharedType>
+void ListeningController<SharedType>::OnEventReceived(const int& event)
+{
+    if (event == INIT_EVENT) {
+        m_so = SharedObjectFactory<SharedType>::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<size_t, bool>::Type SharedTypeList;
+
+class TestSharedObject4;
+typedef std::shared_ptr<TestSharedObject4> TestSharedObject4Ptr;
+
+class TestSharedObject4 : public SharedObject<SharedTypeList>
+{
+  public:
+    enum
+    {
+        SIZE_T,
+        BOOLEAN
+    };
+
+    static TestSharedObject4Ptr Create()
+    {
+        return SharedObjectFactory<TestSharedObject4>::Create(SHM_KEY, SEM_NAME);
+    }
+
+    ~TestSharedObject4()
+    {
+        LogDebug("dtor");
+    }
+
+  protected:
+    explicit TestSharedObject4(const std::string& semaphore) :
+        SharedObject<SharedTypeList>(semaphore)
+    {}
+
+  private:
+    void Init()
+    {
+        SetPropertyInternal<BOOLEAN>(false);
+    }
+    friend class SharedObjectFactory<TestSharedObject4>;
+};
+} // anonymus namespace
+
+//////////////////////////////////////////////
+
+RUNNER_TEST(SharedMemory_002_AccessByType)
+{
+    RemoveIpcs();
+
+    SharedData<TestTypeList> 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<TestTypeList> 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<TestTypeList> 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<SharedMemory::Segment<SharedStruct> > SharedStructPtr;
+
+RUNNER_TEST(SharedMemory_010_BaseShmTest)
+{
+    RemoveIpcs();
+
+    typedef std::unique_ptr<SharedMemory> SharedMemoryPtr;
+
+    // write
+    SharedMemoryPtr shm;
+    Try {
+        shm.Reset(SharedMemory::Create<SharedStruct>(SHM_KEY, false));
+    }
+    Catch(SharedMemory::Exception::NotFound) {
+        shm.Reset(SharedMemory::Create<SharedStruct>(SHM_KEY, true, true));
+    }
+
+    SharedStructPtr str = shm->Attach<SharedStruct>();
+
+    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<SharedStruct>(SHM_KEY, false));
+    }
+    Catch(SharedMemory::Exception::NotFound) {
+        shm2.Reset(SharedMemory::Create<SharedStruct>(SHM_KEY, true, true));
+    }
+
+    SharedStructPtr str2 = shm2->Attach<SharedStruct>();
+    SharedStructPtr str3 = shm2->Attach<SharedStruct>();
+
+    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<SharedTypeList> MySharedObj;
+
+    MySharedObj::Ptr so =
+        SharedObjectFactory<MySharedObj>::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<InitTestSharedObject>;
+};
+
+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<InitTestSharedObject> sho =
+        SharedObjectFactory<InitTestSharedObject>::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<VersionTestSO1>;
+};
+
+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<VersionTestSO2>;
+};
+
+RUNNER_TEST(SharedMemory_022_InvalidVersionTest)
+{
+    RemoveIpcs();   // we need non existing shm
+
+    std::shared_ptr<VersionTestSO1> sho =
+        SharedObjectFactory<VersionTestSO1>::Create(SHM_KEY, SEM_NAME);
+
+    Try {
+        std::shared_ptr<VersionTestSO2> sho2 =
+            SharedObjectFactory<VersionTestSO2>::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<TestTypeList> SO1;
+    typedef SharedObject<TestTypeList2> SO2;
+
+    SO1::Ptr sho = SharedObjectFactory<SO1>::Create(SHM_KEY, SEM_NAME);
+
+    Try {
+        SO2::Ptr sho2 = SharedObjectFactory<SO2>::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<MagicTestSO1>;
+};
+
+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<MagicTestSO2>;
+};
+
+RUNNER_TEST(SharedMemory_024_InvalidMagicTest)
+{
+    RemoveIpcs();   // we need non existing shm
+
+    std::shared_ptr<MagicTestSO1> sho =
+        SharedObjectFactory<MagicTestSO1>::Create(SHM_KEY, SEM_NAME);
+
+    Try {
+        std::shared_ptr<MagicTestSO2> sho2 =
+            SharedObjectFactory<MagicTestSO2>::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<EnumTestSO1>;
+
+    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<EnumTestSO1>
+{
+  public:
+    explicit EnumController(DPL::WaitableEvent* waitable) :
+        ListeningController<EnumTestSO1>(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<EnumTestSO2>;
+};
+
+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<EnumTestSO2> sho2 =
+        SharedObjectFactory<EnumTestSO2>::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<MultiThreadSO>;
+};
+
+void MultiThreadSO::TestAndSetProperty()
+{
+    ScopedFlaggedLock lock(*this);
+
+    int value = PropertyRef<0, int>();
+    DPL::Thread::MicroSleep(100);
+    SetPropertyInternal<0>(value + 1);
+}
+
+class ShmController : public ListeningController<MultiThreadSO>
+{
+  public:
+    explicit ShmController(DPL::WaitableEvent* event) :
+        ListeningController<MultiThreadSO>(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<MultiThreadSO>::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<TestTypeList> SHO;
+    SHO::Ptr sho = SharedObjectFactory<SHO>::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<bool, TestSharedObject4::BOOLEAN, TestSharedObject4>
+    boolValue;
+};
+
+/*
+ * Listening controller
+ */
+class ShmController3 : public ListeningController<TestSharedObject4>
+{
+  public:
+    explicit ShmController3(DPL::WaitableEvent* event) :
+        ListeningController<TestSharedObject4>(event)
+    {}
+
+    virtual void OnEvent(const int event);
+
+    void OnValueChanged(const DPL::PropertyEvent<bool>& event);
+
+  private:
+    typedef std::unique_ptr<MyModel10> 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<bool>& 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<TestSharedObject4::BOOLEAN>(true);
+        Wait(waitable);
+        result = sharedObject->GetProperty<TestSharedObject4::BOOLEAN,
+                                           bool>();
+        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<int, 0, TestSharedObject> counter;
+};
+
+class SPController : public ListeningController<TestSharedObject>
+{
+  public:
+    explicit SPController(DPL::WaitableEvent* event) :
+        ListeningController<TestSharedObject>(event), m_repeats(1) {}
+
+    virtual void OnEvent(const int event);
+
+    void OnValueChanged1(const DPL::PropertyEvent<int>& event);
+    void OnValueChanged2(const DPL::PropertyEvent<int>& event);
+
+  private:
+    std::unique_ptr<MyModel2> m_model1;
+    std::unique_ptr<MyModel2> m_model2;
+
+    int m_repeats;
+    std::shared_ptr<TestSharedObject> m_so2;
+};
+
+void SPController::OnEvent(const int event)
+{
+    if (event == INIT_EVENT) {
+        m_so2 = SharedObjectFactory<TestSharedObject>::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<int>& 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<int>& 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<TestSharedObject>::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<TestSharedObject>,
+    public ISharedObjectListener<0, int>,
+    public ISharedObjectListener<1, int>,
+    public ISharedObjectListener<2, char>,
+    public ISharedObjectListener<3, int[64]>
+{
+  public:
+    explicit ListenerTestController(DPL::WaitableEvent* event) :
+        ListeningController<TestSharedObject>(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<TestSharedObject>::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<bool,
+                             TestSharedObject4::BOOLEAN,
+                             TestSharedObject4> 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<TestSharedObject4::BOOLEAN>(
+        true,
+        MyModel3::PropertyType::SetDelegate(&dao, &DAO::SetBoolValue));
+
+    // check dao value
+    RUNNER_ASSERT(dao.GetBoolValue() == true);
+
+    // check shared object value
+    bool shoValue = sho->GetProperty<TestSharedObject4::BOOLEAN, bool>();
+    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<TestSharedObject4::BOOLEAN, bool>();
+    RUNNER_ASSERT(shoValue == false);
+
+    // check property value
+    RUNNER_ASSERT(model.boolValue.Get() == false);
+}
+
+//////////////////////////////////////////////
+
+/*
+ * Lazy initialization test shared object
+ */
+class LazySharedObject : public SharedObject<TestTypeList>
+{
+  private:
+    LazySharedObject() :
+        m_read(false)
+    {}
+
+  public:
+    explicit LazySharedObject(const std::string& semaphore) :
+        SharedObject<TestTypeList>(semaphore)
+        , m_read(false)
+    {}
+
+    void Init();
+
+    bool IsRead() const
+    {
+        return m_read;
+    }
+
+  private:
+    friend class SharedObjectFactory<LazySharedObject>;
+
+    bool m_read;
+};
+
+void LazySharedObject::Init()
+{
+    SetPropertyInternal<0>(42);
+    m_read = true;
+}
+
+RUNNER_TEST(SharedMemory_100_LazyInit)
+{
+    RemoveIpcs();
+
+    typedef std::shared_ptr<LazySharedObject> LazySharedObjectPtr;
+
+    // create shared object
+    LazySharedObjectPtr sho = SharedObjectFactory<LazySharedObject>::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<LazySharedObject>::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<LazySharedObject>::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<TestSharedObject>::Create(
+            SHM_KEY,
+            SEM_NAME);
+
+    g_delegateCalls = 0;
+
+    RUNNER_ASSERT(0 == (sho->GetProperty<0, int>()));
+
+    std::function<bool (const int&, int&)> condition = SetCondition;
+    std::function<void (const int&)> 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<TestTypeList>
+{
+  public:
+    explicit MTSharedObject(const std::string& semaphore) :
+        SharedObject<TestTypeList>(semaphore)
+    {}
+
+    void Clear();
+
+  private:
+    friend class SharedObjectFactory<MTSharedObject>;
+};
+
+typedef std::shared_ptr<MTSharedObject> MTSharedObjectPtr;
+
+void MTSharedObject::Clear()
+{
+    int array[64] = {};
+    SetProperty<0>(0);
+    SetProperty<1>(0);
+    SetProperty<2>(static_cast<char>(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<MTSharedObject>::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<MTSharedObject>,
+    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<MTSharedObject>(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<TestSharedObject>::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 (file)
index 0000000..bc2b7e0
--- /dev/null
@@ -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 <dpl/naive_synchronization_object.h>
+
+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 (file)
index 0000000..a885dcd
--- /dev/null
@@ -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 <dpl/test_runner.h>
+#include <dpl/task.h>
+#include <dpl/log.h>
+
+RUNNER_TEST_GROUP_INIT(DPL)
+
+class MySingleTask :
+    public DPL::TaskDecl<MySingleTask>
+{
+  protected:
+    void StepOne()
+    {}
+
+  public:
+    MySingleTask() :
+        DPL::TaskDecl<MySingleTask>(this)
+    {
+        AddStep(&MySingleTask::StepOne);
+    }
+};
+
+class MyMultiTask :
+    public DPL::MultiTaskDecl<MyMultiTask>
+{
+  protected:
+    typedef DPL::MultiTaskDecl<MyMultiTask> 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 (file)
index 0000000..f17421b
--- /dev/null
@@ -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 (file)
index 0000000..7dac1fc
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+#include <dpl/utils/bash_utils.h>
+#include <dpl/log/log.h>
+
+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 (file)
index 0000000..42ffe3a
--- /dev/null
@@ -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 <dpl/test/test_runner.h>
+
+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 (file)
index 0000000..e612ad7
--- /dev/null
@@ -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 <set>
+#include <memory>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/scoped_dir.h>
+#include <dpl/scoped_free.h>
+#include <dpl/utils/path.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/binary_queue.h>
+#include <dpl/file_input.h>
+#include <dpl/file_output.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+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<char> 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<char> 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<char> 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<char> 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<char> 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<char> 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<char> 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<char> 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<char> 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<std::string> resultSet;
+    std::set<std::string> 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<Path::Iterator> 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<Path::Iterator> 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 (file)
index 0000000..5d2bc71
--- /dev/null
@@ -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 <sstream>
+#include <dpl/test/test_runner.h>
+#include <dpl/utils/widget_version.h>
+
+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<DPL::String>());
+    RUNNER_ASSERT(version.Optional() == DPL::Optional<DPL::String>());
+    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<DPL::String>());
+    RUNNER_ASSERT(version.Optional() == DPL::Optional<DPL::String>());
+    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<DPL::String>(L"3"));
+    RUNNER_ASSERT(version.Optional() == DPL::Optional<DPL::String>());
+    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<DPL::String>(L"3"));
+    RUNNER_ASSERT(version.Optional() == DPL::Optional<DPL::String>(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<DPL::String>(L"3"));
+    RUNNER_ASSERT(version.Optional() == DPL::Optional<DPL::String>(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<DPL::String>());
+    RUNNER_ASSERT(version.Optional() == DPL::Optional<DPL::String>(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<DPL::String>());
+    RUNNER_ASSERT(version.Optional() == DPL::Optional<DPL::String>(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<DPL::String> microV = DPL::Optional<DPL::String>();
+    DPL::Optional<DPL::String> optionalV = DPL::Optional<DPL::String>();
+    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::String>(), DPL::Optional<DPL::String>());
+
+    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::String>(), DPL::Optional<DPL::String>());
+
+    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<DPL::String> microV = DPL::Optional<DPL::String>(L"1");
+    DPL::Optional<DPL::String> optionalV = DPL::Optional<DPL::String>();
+    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<DPL::String>(L"1a"), DPL::Optional<DPL::String>());
+
+    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<DPL::String>(L"a1"), DPL::Optional<DPL::String>());
+
+    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<DPL::String> microV = DPL::Optional<DPL::String>(L"1");
+    DPL::Optional<DPL::String> optionalV = DPL::Optional<DPL::String>(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<DPL::String>(L"a1"), DPL::Optional<DPL::String>(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::String>(), DPL::Optional<DPL::String>());
+
+    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::String>(), DPL::Optional<DPL::String>());
+
+    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<DPL::String>(L"12"), DPL::Optional<DPL::String>(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 (file)
index 0000000..710b578
--- /dev/null
@@ -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 <string>
+#include <fstream>
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/log/log.h>
+
+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 (file)
index 0000000..2bf1d96
--- /dev/null
@@ -0,0 +1,170 @@
+indent_align_string=true\r
+indent_braces=false\r
+indent_braces_no_func=false\r
+indent_brace_parent=false\r
+indent_namespace=false\r
+indent_extern=false\r
+indent_class=true\r
+indent_class_colon=false\r
+indent_else_if=false\r
+indent_func_call_param=false\r
+indent_func_def_param=false\r
+indent_func_proto_param=false\r
+indent_func_class_param=false\r
+indent_func_ctor_var_param=false\r
+indent_template_param=false\r
+indent_func_param_double=false\r
+indent_relative_single_line_comments=false\r
+indent_col1_comment=true\r
+indent_access_spec_body=false\r
+indent_paren_nl=false\r
+indent_comma_paren=false\r
+indent_bool_paren=false\r
+indent_square_nl=false\r
+indent_preserve_sql=false\r
+indent_align_assign=false\r
+sp_balance_nested_parens=false\r
+align_keep_tabs=false\r
+align_with_tabs=false\r
+align_on_tabstop=false\r
+align_number_left=false\r
+align_func_params=false\r
+align_same_func_call_params=false\r
+align_var_def_colon=false\r
+align_var_def_attribute=false\r
+align_var_def_inline=false\r
+align_right_cmt_mix=false\r
+align_on_operator=false\r
+align_mix_var_proto=false\r
+align_single_line_func=false\r
+align_single_line_brace=false\r
+align_nl_cont=false\r
+align_left_shift=true\r
+nl_collapse_empty_body=true\r
+nl_assign_leave_one_liners=false\r
+nl_class_leave_one_liners=false\r
+nl_enum_leave_one_liners=false\r
+nl_getset_leave_one_liners=false\r
+nl_func_leave_one_liners=false\r
+nl_if_leave_one_liners=false\r
+nl_multi_line_cond=true\r
+nl_multi_line_define=false\r
+nl_before_case=false\r
+nl_after_case=false\r
+nl_after_return=false\r
+nl_after_semicolon=true\r
+nl_after_brace_open=false\r
+nl_after_brace_open_cmt=false\r
+nl_after_vbrace_open=false\r
+nl_after_brace_close=false\r
+nl_define_macro=false\r
+nl_squeeze_ifdef=false\r
+nl_ds_struct_enum_cmt=false\r
+nl_ds_struct_enum_close_brace=false\r
+nl_create_if_one_liner=false\r
+nl_create_for_one_liner=false\r
+nl_create_while_one_liner=false\r
+ls_for_split_full=true\r
+ls_func_split_full=true\r
+nl_after_multiline_comment=false\r
+eat_blanks_after_open_brace=true\r
+eat_blanks_before_close_brace=true\r
+mod_pawn_semicolon=false\r
+mod_full_paren_if_bool=false\r
+mod_remove_extra_semicolon=true\r
+mod_sort_import=false\r
+mod_sort_using=false\r
+mod_sort_include=false\r
+mod_move_case_break=false\r
+mod_remove_empty_return=false\r
+cmt_indent_multi=true\r
+cmt_c_group=false\r
+cmt_c_nl_start=false\r
+cmt_c_nl_end=false\r
+cmt_cpp_group=false\r
+cmt_cpp_nl_start=false\r
+cmt_cpp_nl_end=false\r
+cmt_cpp_to_c=false\r
+cmt_star_cont=true\r
+cmt_multi_check_last=true\r
+cmt_insert_before_preproc=false\r
+pp_indent_at_level=false\r
+pp_region_indent_code=false\r
+pp_if_indent_code=false\r
+pp_define_at_level=false\r
+indent_columns=4\r
+indent_member=4\r
+indent_access_spec=-2\r
+code_width=80\r
+nl_max=2\r
+nl_before_access_spec=2\r
+cmt_width=80\r
+indent_with_tabs=0\r
+sp_arith=force\r
+sp_assign=force\r
+sp_enum_assign=force\r
+sp_pp_concat=remove\r
+sp_pp_stringify=remove\r
+sp_bool=force\r
+sp_compare=force\r
+sp_paren_brace=force\r
+sp_angle_paren=remove\r
+sp_before_sparen=force\r
+sp_inside_sparen=remove\r
+sp_after_sparen=force\r
+sp_sparen_brace=force\r
+sp_before_semi=remove\r
+sp_after_semi_for_empty=remove\r
+sp_before_square=remove\r
+sp_before_squares=remove\r
+sp_inside_square=remove\r
+sp_after_comma=force\r
+sp_before_comma=remove\r
+sp_after_class_colon=force\r
+sp_before_class_colon=force\r
+sp_before_case_colon=remove\r
+sp_inside_braces=add\r
+sp_inside_fparens=remove\r
+sp_inside_fparen=remove\r
+sp_func_call_paren=remove\r
+sp_func_class_paren=remove\r
+sp_else_brace=force\r
+sp_brace_else=force\r
+sp_catch_brace=force\r
+sp_brace_catch=force\r
+sp_try_brace=force\r
+sp_before_dc=remove\r
+sp_after_dc=remove\r
+sp_not=remove\r
+sp_inv=remove\r
+sp_addr=remove\r
+sp_member=remove\r
+sp_deref=remove\r
+sp_sign=remove\r
+sp_incdec=remove\r
+sp_cond_colon=force\r
+sp_cond_question=force\r
+sp_case_label=force\r
+nl_assign_brace=remove\r
+nl_if_brace=remove\r
+nl_brace_else=remove\r
+nl_elseif_brace=remove\r
+nl_else_brace=remove\r
+nl_else_if=remove\r
+nl_try_brace=remove\r
+nl_for_brace=remove\r
+nl_catch_brace=remove\r
+nl_brace_catch=remove\r
+nl_while_brace=remove\r
+nl_do_brace=remove\r
+nl_brace_while=remove\r
+nl_switch_brace=remove\r
+nl_namespace_brace=remove\r
+nl_class_brace=force\r
+nl_fdef_brace=force\r
+pos_class_comma=trail\r
+pos_class_colon=trail\r
+mod_full_brace_do=add\r
+mod_full_brace_for=add\r
+mod_full_brace_if=add\r
+mod_full_brace_while=add\r
diff --git a/uncrustify.sh b/uncrustify.sh
new file mode 100755 (executable)
index 0000000..2ccffef
--- /dev/null
@@ -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 (file)
index 0000000..a285a63
--- /dev/null
@@ -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 (file)
index 0000000..6b910cf
--- /dev/null
@@ -0,0 +1,15 @@
+<manifest>
+  <define>
+    <domain name="wrt-commons"/>
+    <provide>   
+        <label name="wrt-commons::db_wrt"/>
+    </provide>
+  </define>
+  <request>
+    <domain name="_"/>
+  </request>
+  <assign>
+    <filesystem path="/usr/bin/wrt_commons_create_clean_db.sh" label="_" exec_label="none"/>
+    <filesystem path="/usr/bin/wrt_commons_reset_db.sh" label="_" exec_label="none"/>
+  </assign>
+</manifest>